但是,那么多优秀的开源项目总是带有非常详细的注释,难道是烂代码不成。反正不管好代码还是烂代码,就算是没有注释的好代码,读起来也比有注释完备的烂代码难读、难懂。
再者说,什么是好代码,这个标准很难评。
没有bug的代码就是好代码吗?性能优越的就是好代码吗?还是说简单易懂的就是好代码呢?
图片
不知道你有没有碰到过下面这几种场景:
(一) 同事问你,或者你问同事:“你这代码怎么没注释?”有多少人会回答是因为我代码写的好,不需要注释的。就算真有人这么说,得到的回复也是「辣鸡,什么都不是」。
(二) 某个项目或者某块功能突然要补上设计文档,而功能又不是你做的。你可能会说:得看看这部分代码有没有注释,没有注释的话,可能得多需要一些时间。然后写的过程,如果真的没有注释,大概率也会在心里嘀咕『代码写这么烂,还不加注释』
(三) 你接手了一个新项目,要改一些功能,如果碰巧这些功能有注释,你会谢天谢地,然后谢谢当初写代码加注释的家伙。
无论是我们看自己之前的代码,还是接手别人的代码,有注释是百利而无一害的。
“Redis 之父” antirez 将注释分为 9 种类型,其中前6种是提倡的,后三种是最好要避免的。
1、函数注释
目的是让读者无需先读代码,可将某些代码视为黑盒,通常位于函数定义顶部或其他功能性代码块处,类似内联 API 文档,可确保文档与代码同步更新、提高作者修改文档的概率、方便读者查找文档。
很多时候我们只是想使用某个方法,而其内部可能很复杂,比如某个非常专业的算法,可能读半天都看不懂, 这种情况,如果有对方法的说明,我们只要根据说明来用就可以了。
一些开放API就类似于这种注释,我们经常抱怨某大厂的开放平台 API 文档写的那叫一个垃圾,根据说明文档来会踩很多坑。同理,如果一个复杂的方法没有注释,或者注释很垃圾,会给使用者带来很多麻烦。
2、设计注释
常位于文件开头,说明代码使用特定算法等的方式和原因,提供更高层次的概述,有助于读者理解代码,且能让读者了解设计过程,增强对代码的信任。
大的开源项目中几乎每个文件都有这种注释,用来解释这个文件是干什么用的。
3、Why 注释
解释代码为什么要做某事,即使代码行为很清晰,这种注释可能是思考系统改进的机会。
比如代码中做了某些特别的操作或动作,如果纯靠读代码,不知道上下文,比如涉及到某个业务,那会让使用者一头雾水,知其然不知其所以然。
4、Teacher 注释
教学代码,对读者有很大价值,能增加可阅读代码的程序员数量。
很多技术文章或者源码解读中都有这样的注释,比如写 HasMap
原理的文章,其中涉及到存储结构、哈希冲突、扩容这些原理时,一定是对着代码将会更清楚,所以多采用在方法中逐行加注释的方法来说明,读者一行注释一行代码看下来,可以更加轻松的搞清楚内在逻辑。
5、Checklist 注释
由于语言限制等原因,代码中某些概念或接口无法集中在一处时,这种注释会提醒在修改代码的某些部分时要记得修改其他部分,或者警告特定修改的操作方式,在 Linux 内核中很常见。
这很像是对一个事务的解释,一个事务会涉及到多个阶段,但是每个阶段要执行的东西可能会分散到各处,当你读到其中的某个阶段代码时,如果有 Checklist 告知你整个事务链条,那你对这个事务会理解的更加清晰。
6、Guide 注释
辅助读者阅读代码,降低认知负担,明确划分代码、引入即将阅读的内容,虽主观但对提高代码可读性有帮助,还能使新增代码更可能插入到合适位置。
这更像是一个项目的 README 文件,好的开源项目一定有一个好的 README 文档,告诉使用者需要什么环境、要安装什么依赖包、如何配置参数、如何启动等等。
7、琐碎注释
一些无用且琐碎的评论,比如一行非常简单的代码,确实是那种一眼就能看懂的代码,还非要加上注释。
比如下面这个自增语句,非要加个注释,莫名其妙的,有这功夫,还是把主要逻辑的注释写好吧。
count++; // 自增
8、债务注释
即代码中的技术债务声明,如 TODO、FIXME 等,虽不太好但有时可避免遗忘问题,应定期检查并处理。
有时候为了快速的实现功能,可能有些逻辑会有临时性的快速方案,然后在对应的位置加上 TODO
,之后可能临时方案就变成最终方案了。
9、Backup 注释
开发者对旧版本代码块或函数进行注释,因对新代码不放心,但这是不合适的,源代码不是用来做备份的。
说实话,我有时也会这么干,写新方法时,先把把旧方法注释掉,万一有问题的话,直接注释掉,省的代码回滚了。
在业务频繁变更的时候,这种方法确实也没什么问题,只要想着在稳定之后把注释的无用方法删掉就好了。
同样是接手一份代码,如果是没有注释的,我们在接手的时候就难免会先产生反感、畏难情绪,除非注释是乱写的。
我还真见过方法注释和方法逻辑驴唇不对马嘴的,严重怀疑是前辈不想干了,在代码里下毒。你要是真按照他注释的来,那就废了。
最起码就我而言,我觉得加注释的代码比不加注释的代码要更友好。加上现在各种AI代码助手,更应该写注释了,比如你用 Cursor 写代码,你先写注释,然后让 Cursor 给你写代码就好了,所以说以后写注释可能是一项必备技能,然后是 Review AI 写的代码,最后才是写代码的能力了。