写注释的关键指导原则就是尽量帮助读者了解跟作者一样多。
1、不必要的注释
如果能从代码本身看出的事实写注释。
这样注释完全多余,从代码本身就可以看出代码的意思。
也不能使用跟代码一样的意思重复注释,比如:
//Find a Node with the given 'name' or return NULL
Node * FindNodeInSubtree(Node* subtree,char *name,int depth)
上面的注释相当于把函数名重写了一遍,如果非要加注释,可以加上函数内部的细节。
//Find a Node with the given 'name' or return NULL
//If depth <= 0 ,only 'subtree' is inspected.
//If depth == N,only 'subtree and N levels below are inspected.
Node * FindNodeInSubtree(Node* subtree,char *name,int depth)
以前曾说过把信息装到名字中及不要起能引起误解的名字,这里要说不要为不好的名字加注释。如:
//Enfore limits on the Reply as stated in the Request,
//such as the number of items returned ,or total byte size ,etc.
void CleanReply(Request request,Reply reply)
上面的注释大部分内容都在解释clean是什么意思,这种情况属性名字起得不合适。从注释上,函数是限制返回的限制,所以把Enfore limits放到名字里,然后解释限制内容就可以了。
//make sure 'reply' meets the count.byte,etc,limits from the 'request'
//void EnforceLimitsFromRequest(Request request,Reply reply)
还有会引起误解的名字,就不要加注释了,应该直接改掉名字。
2、注释是要记录你的思想
用添加导演评论的方式。
//出乎意料的是,对于这些数据用二叉权比哈希表快40%
//哈希运算的代码比左/右比较大得多
上面这段注释会都读者去做无谓的优化。
//作为整体可能会丢掉几个单词。这没有问题。要100%解决太难了。
这段注释是告诉读者不要把这当成bug。
为代码中要改进,没有完成的写注释:
//TODO:采用更快算法
//TODO(dustin):去处理其它
给常量加注释,增加背后的故事:
常量有时候从名字可以准确知道它代表的意思,但是其背后的故事可以告诉使用人更多使用信息。
NUM_THREADS = 8//as long as it's >=2*num_processors,that's good enough。
使用这个常量的人就知道如何调整它了。再如,
const int MAX_RSS_SUBSCRIPTIONS =1000//impose a reasonable limit-no human can read that much anyway.
image_qulity=0.72//users thought 0.72 gave the best size/qulity tradeoff.
以上是告诉使用者这些量是经过认真确定的,真的无须改动。但是对于像SECONDS_PER_DAY这样的量,就无须加注释了。
3、站在读者角度来注释
站在对方角度考虑可能存在的陷井,考虑别人使用时会遇到的问题。
比如一个使用外部服务器发送邮件的函数:
void SendEmail(string to ,string subject,string body)
这个函数实现包括连接到外部服务器,这可能会花一秒或者更多。可能有人在写程序时,调用该服务导致挂起。为了避免这样,你可能为这个细节加上注释:
//调用外部服务来发送邮件。(1分钟后超时)
void SendEmail(string to ,string subject,string body)
注重全局性注释,像文件级别的注释及模块级别的注释,可以让读者很快掌握整个代码接口结构。
注释代码时注重为什么这么做,而不是做什么!!!