加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

Redis是如何写代码注释的?

发布时间:2018-12-20 17:24:49 所属栏目:编程 来源:数据库开发
导读:许多人认为,如果代码写得足够扎实,注释就没什么用了。在他们看来,当一切都设计妥当时,代码本身会记录其作用,因此代码注释是多余的。我对此持不同意见,主要出于两个原因: 1、许多注释并未起到解释代码的作用。 2、注释使读者不必凭空想象太多细枝末
副标题[/!--empirenews.page--]

Redis是如何写代码注释的?

许多人认为,如果代码写得足够扎实,注释就没什么用了。在他们看来,当一切都设计妥当时,代码本身会记录其作用,因此代码注释是多余的。我对此持不同意见,主要出于两个原因:

1、许多注释并未起到解释代码的作用。

2、注释使读者不必凭空想象太多细枝末节,帮助读者降低认知负担。

注释的分类

我的工作始于随机地阅读Redis源代码,以检查注释是否以及为什么在不同的上下文中起作用。我很快发现,注释的作用来源于多方面:它们在功能,编程风格,长度和更新频率方面往往非常不同。我最终转向了注释分类。

在研究期间,我确定了九种注释类别:

* 函数注释 Function comments

* 设计注释 Design comments

* 原因注释 Why comments

* 教学注释 Teacher comments

* 清单注释 Checklist comments

* 引导注释 Guide comments

* 琐碎注释 Trivial comments

* (代码)负债注释 Debt comments

* 备份注释 Backup comments

在我看来,前六个主要是非常积极的注释形式,而最后三个有点值得怀疑。在接下来的部分中,我将使用Redis源代码中的示例分析每种注释类型。

函数注释

函数注释的目标是防止读者直接阅读代码。

在阅读注释之后,读者应该可以将一些代码视为应遵守某些规则的黑箱子。通常情况下,函数注释位于函数定义的顶部。

rax.c:

  1. / * 在当前节点的子树中寻找最大的key。 
  2.     如果内存不足返回0,否则 返回1. * / 
  3. int raxSeekGreatest(raxIterator * it){ 
  4.     ... 

函数注释实际上是一种内联API文档。如果函数注释编写得好,那么用户在大多数时候能跳回到她正在阅读的内容(如阅读调用此类API的代码),而无需阅读函数(function),类(class),宏(macro)等的实现过程。

在所有注释类型中,函数注释被整个编程界广泛接受和需要。要分析的唯一一点是:在代码内部放置以API参考文档为主的注释是否是件好事。

对我来说答案很简单:我希望API文档与代码完全匹配。随着代码的更改,文档也得到更改。出于这个原因,我们将函数注释用作函数或其他元素的序言,使API文档接近代码,完成三个任务:

* 随着代码的更改,我们可以轻松更改文档,API参考也不会有过时的风险。

* 这种方法使得更改者(理应是最清楚更改目的的人)在最大限度上成为API文档的更改者。

* 读者能通过阅读代码直接找到函数或方法(method)的文档,以便阅读代码的读者只关注代码,而不是代码和文档之间的上下文切换。

设计注释

“函数注释”通常位于函数的开头,而设计注释通常位于文件的开头。

设计注释一般说明了给定代码片段使用某些算法、技术、技巧和具体实现的方式和原因,对代码中实现的内容进行了更高级别的概述。在这样的背景下,阅读代码会更简单一些。

bio.c

  1. *设计 
  2. * ------ 
  3. *设计很简单,我们用一个结构代表要执行的一项 Job 
  4. *每种Job类型有不同的线程和Job队列。 
  5. *每个线程都在等待队列中的新Job,并按照顺序处理 
  6. *每个Job。 
  7.  ... 

原因注释

原因注释解释了代码执行某些操作的原因——即使代码执行的操作非常明确。请看以下来自Redis replication的代码 的示例。

replication.c:

  1. if(idle> server.repl_backlog_time_limit){ 
  2.  
  3. /* 当我们释放 backlog时,我们总是使用新的 
  4.  * replication ID并清除ID2。这是 
  5.  * 因为在没有backlog时,master_repl_offset 
  6.  * 未更新,但我们仍会保留我们的 
  7.  * replication ID,由此导致以下问题: 
  8.  * 
  9.  * 1.我们是一个主实例(master instance)。 
  10.  * 2.我们的副本成为主服务器(Master)。repl-id-2将会 
  11.  *   与我们的repl-id相同。 
  12.  * 3.我们作为主服务器,收到了一些更新命令,但不会 
  13.  *   增加master_repl_offset。 
  14.  * 4.稍后我们将变成副本,连接到新的 
  15.  *   主服务器,它将接受我们第二个副本ID的 
  16.  *   PSYNC请求,但会有数据不一致的情况 
  17.  *   因为我们接受了写命令。* / 
  18.  
  19. changeReplicationId(); 
  20. clearReplicationId2(); 
  21. freeReplicationBacklog(); 
  22. serverLog(LL_NOTICE, 
  23.     "Replication backlog freed after %d seconds " 
  24.     "without connected replicas.", 
  25.     (int) server.repl_backlog_time_limit); 

如果我只检查函数调用,就没什么需要纠结的:如果超时了就更改主replication ID,清除辅助ID,最后释放replication backlog。

教学注释

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读