我曾经在生产关键软件的商店工作过,还处理过注释规则,这些规则旨在保持代码的可读性并可能挽救生命。以我的经验,尽管要求变成了脑力劳动,要从清单中剔除,但这并不能帮助我专注于编写可理解的代码。这也分散了我的同行审稿人的注意力,使我无法与我进行更有意义的对话,以使代码更易于理解。

我还对没有评论的学生代码进行了评分,并查看了为什么要对它们进行标记

我理解使用好名字,保持结构简单,函数简短以及专注于模块将使代码易于理解,以使注释最小化。

我也理解注释应该解释为什么代码会做什么,而不是怎么做。在同行评审中将是相关的,但不会变成漫不经心的清单活动,该活动不会产生比以下内容更有用的注释:“您忘记对第42行进行评论”。

在清单中被视为一行时,可能需要使用此规则的代码:

可能并非如此,我想沿用以下思路:

为每行,序列,语句,节,结构,函数,方法,类,包,组件考虑注释,...的代码。接下来考虑重命名和简化以消除对该注释的任何需要,因此您可以将其删除。在评论很少的情况下签入。重复直到截止日期。然后再重复一些

评论

评论不作进一步讨论;此对话已移至聊天。

“注释不适合扩展讨论”,对于代码注释更是如此。 :)那些/ *显示错误消息* /注释很可怕,实际上会影响可读性。

我们需要我们的IDE具有隐藏注释的选项。阻止和嵌入式注释分别隐藏的选项。这样一来,您就可以充分利用这两种选择。放入很多注释,但可以选择隐藏它们以保持代码整洁,整洁。

@ Doug.McFarlane我认为vim应该存在。当然,它在文件级别和块级别都可以-rtfm-sarl.ch/articles/hide-comments.html!

同时切换-stackoverflow.com/a/11842371/631619

#1 楼

迈克尔·杜兰特(Michael Durrant)的回答是恕我直言,还不错,但这并不是从字面上回答这个问题(正如他本人所承认的那样),因此我将尝试给出一个答案:解释为什么代码会执行它的工作,而不是如何执行。评论,其中包含诸如“

”之类的问题,“如果有评论,它是否解释了代码为什么要这样做?” -足够说明性,不需要注释,或者如果不需要注释,是否附带注释可以缩小差距?或者(最好)是否可以更改代码以使其不再需要注释?”

如果愿意,可以将其称为“编码标准”(或者不可以,如果您认为术语“编码标准”应该保留给脑死亡规则的列表使用,那么如果不满足则容易回答) w代码的格式应该看起来像,或在哪里声明变量)。没有人会妨碍您将检查表的重点放在语义问题上,而不是走简单的路线,只将正式的规则放入其中。
最后,您应该确保您的团队需要这样的检查表。要解决这些问题,您需要具有一定经验的程序员作为审阅者,并且需要在专家团队中确定它是否真的可以提高代码的可读性。但这是您必须与团队共同努力的事情。

评论


谁对此表示反对?这是关键软件开发的答案。与大多数程序员的工作环境相比,这是一个不同的世界。在这些情况下,要求每一行代码都有自己的注释的编码标准不是正确的答案。都没有放弃的评论。 OTOH,使注释经受代码审查是针对关键软件的正确标准。它使代码更易于检查和维护,但这是有代价的。与编写不良软件引起的数百万美元的诉讼相比,这笔钱简直是小巫见大巫。

–David Hammen
16 Nov 20在22:05



明智的答案。如果我们可以找到真正的编码规则,则不需要程序员。我们只需要机器代码。有可能发生! :(

–user223083
16-11-20在22:29

@DavidHammen:感谢您的评论。实际上,我认为这不仅适用于“关键软件开发”。往往由不同的人维护和发展了数年的每一款软件,都将受益于对下一维护程序员的理解。

–布朗博士
16年11月21日在7:10

对于任何编码,这都是很好的建议,而不仅仅是由不同人员维护的代码。即使您是唯一使用脚本/程序的人,将来您也必须在一年的时间内修改代码,这将使您很清楚(以及不必解密不透明代码所节省的时间)。

– Anthony Geoghegan
16年11月21日在10:24

您可以将“当前最受好评的答案”编辑为更客观的内容吗?并非每个读者都会知道这些答案的投票历史。

–candied_orange
16年11月23日在1:05

#2 楼

主要反模式导致质量较差的代码,但清晰度较低。

顺便说一下,标题最初是“注释每一行代码?您可以想象我们当中包括我在内的许多人的本能反应。

起初,我改了称号。

起初,阅读您认为的问题,评论中有很多重复的内容,但是好吧,如果您对多人的评论有足够的限制...但是再说一遍:人们会犯错误,无法注意到不一致之处等,随着时间的流逝,最终将出现分歧。经过反思,我认为问题要大得多:

开发人员将倾向于编写更糟糕的代码。他们将使用更多隐秘的名称和结构,因为“其注释中有解释-请看!”。

考虑:

living_room_set = tables + chairs.

您不仅要拥有更多的神秘名称和更多的可读性,而且还得来回回头,看一下代码,什么是集合?左看代码,右看注释,什么是tbls,左看代码,右看注释,什么是chrs,右看注释。 Yuch!

摘要

如果您被迫担任开发人员的当前职位,请开发或增强评论标准(作为前COBOL编程的人,我肯定看到过大的!),但花费了您大量的时间,精力和激情,使用以下参数来反对注释反模式:变化
评论可能会描述一个人的想法,但可能是错误的,从而掩盖了错误名称
要在代码和注释中读取过多的字符
不同的编辑使用不同的样式
与仅仅编码相比,要求更高的英语水平
花费时间和资源并从长期价值中减去*

再加上争取更好的代码而没有这样的注释-实际上有一个标准(!)-所有变量名都必须为full_english_words-有一个!因此,请将“标准”能量用于编写良好的代码和测试的标准。

两个棘手的问题之一是事物的命名-不要在注释旁跳过问题。一般情况下,可能会导致模糊的“为什么这样”代码,尽管上述注意事项仍然适用,但在这一领域中,对于显然效果较差的代码的解释性注释可能会有所帮助。

评论


我不相信您回答了这个问题。问题不在于每行都有评论。它正在询问如何告诉开发人员注释代码而不导致他们注释每一行。

–hichris123
16-11-20在22:58

是的,我没有回答具体的标准问题,而是试图帮助人们不要走这条路。因此,这可能不是特定问题的答案,但确实包含了难以在评论中提出的宝贵建议。

–迈克尔·杜兰特(Michael Durrant)
16年11月21日,0:34

另一个难题是什么?

–大卫说恢复莫妮卡
16年11月21日在16:13

@DavidGrinberg缓存无效和一字不漏的错误。

–埃里克·金(Eric King)
16年11月21日在17:07

您可以避免注释的每一个理由都可以反驳,但是StackExchange不允许足够长的注释(heh)允许我在此处解决所有问题。简而言之:过度评论就像选民欺诈一样:确实会发生,但很少发生;您最后一次真正看到它发生的时间是什么时候?写出好的评论不应该只是事后的想法。如果做得正确,将有助于开发过程。是的,这需要资源,但是收益是更好的代码。通过牺牲注释以获得更好的变量命名标准,您将永远无法获得相同的收益。是的,对每一行发表评论是很疯狂的。

– kmoser
16-11-27在2:10



#3 楼

我不认为编码标准文档是指定已经是常识的地方。编码标准的目的是保证在合理的人可能不同意且没有单一明显的正确答案(例如命名约定,缩进等。

示例中的这种注释在客观上是无用的,并且可能是由于没有经验的开发人员或曾经使用过构建系统的开发人员来机械检查是否存在评论(一个非常糟糕的主意,但是它存在)。在这两种情况下,解决方案都是教育,可能需要通过代码审查。

如果您开始将各种“最佳实践”添加到编码标准中,则最终将重复出现在多本书中。只需向有问题的开发人员购买“干净代码”,“代码完整”和“实用程序员”,并保持代码标准精简即可。

评论


经过40多年的学习,我在球拍中学到的许多东西之一是常识根本不是常识。

– John R. Strohm
16年11月20日在18:25

没有常识。

–whatsisname
16年11月20日在18:41

在编程中没有。真实世界哦,是的,但这只是真实世界经验知识的一个术语

–迈克尔·杜兰特(Michael Durrant)
16年11月20日在22:15

@ JohnR.Strohm:我的经验比您的经验要积极得多,但是我也看到了如何通过机械地执行规则积极地阻止使用常识。

–雅克B
16年11月22日在14:10

我对这个答案有99.9%的同意。编码标准旨在成为开发人员在Code Review上发生辩论时要指出的内容。代码审查旨在丰富产品而不是发动战争。没有代码标准的代码审查激起了如此多的战争。我敢说,如果您不能自动检查编码标准中的项目,则应该在其中。代码审查是时候向其他经验不足的开发人员传授“常识”。现在不是争夺变量命名的时候。 linux / kernel / gen_init_cpio.c第335行。

–安德鲁(Andrew T Finnell)
16-11-23在14:37

#4 楼

这不可能。实际上,您要做的几乎是机械化良好的判断力。不仅聪明的人都会犯错,而且这些设备的很多软件都是由不太擅长工作的人编写的,因此“系统”必须能够防范草率的工作,使其安全

您最好的选择是省去严格的编码标准以发表评论,并以团队为榜样。通过努力产生适当注释的高质量代码来显示他人的良好注释。与其尝试找到描述如何编写注释的终极方式(它们本身常常是判断调用),不如通过自己的代码审查每天向其他人展示您的意思。当其他成员阅读您的代码时,如果他们觉得有用,他们也会效仿。如果他们做不到,那么没有标准可以帮助他们写出更好的评论。

评论


+1表示“您正在努力使良好的判断力机械化”,-1表示“您唯一的选择就是只希望获得最好的成绩”,这使我无法投票。也可以对团队进行教育和培训。标准可以进行判断。

–通配符
16-11-23在2:35



@Wildcard也许您可以解释标准如何允许判断?那不是那时的指南吗?标准是“在比较评估中用作度量,规范或模型的想法或事物”。一个人如何才能使用本质上是主观的东西,所以它的主观性取决于谁在阅读,以此来衡量质量?

–安德鲁(Andrew T Finnell)
16年11月23日在15:52

@Wildcard:问题在于,当您进入受管制的行业时,该过程在所有方面都至高无上,拥有一个过程比该过程是否值得更重要。一切都必须归结为某种形式的复选框,每个复选框都必须是特定且可验证的,并且您在复选框中拥有的余地越多,则在审核中遇到麻烦的风险就越大。

–whatsisname
16年11月23日在17:51

这是一个陌生的世界,请记住,规则是由对软件领域一无所知的官僚编写的,并且您通常最终会获得存在的系统来证明自己并要求自己,而不是作为确保高质量产品的手段。

–whatsisname
16年11月23日在17:52

@whatsisname我很高兴有其他了解的人。您的回复写得比我以前努力的要优雅,准确。我的系统存在的陈述足以证明并要求自己,而不是作为确保高质量产品的一种手段,正是我所试图说明的。感谢您为我找到我的话。我是真的我们必须将提高质量的想法与遵循流程的想法区分开,因为它们是不同的。这就是为什么我们有QA,S​​tackoverflow和非常宽容的客户的原因。

–安德鲁(Andrew T Finnell)
16-11-23在18:10



#5 楼

更新
我在引号中的回答重点在于:

我相信答案中指出不应在编码标准中提及评论,然后列出了一系列防御性的问题可以解决。唯一正确的答案。
这里的问题是编码标准就是标准。极端主观的想法不应包含在编码标准中。它可以是“最佳实践”指南中的,但是在“代码审阅”期间不能将该指南用于开发人员。我个人认为,编码标准应尽可能接近自动。当所有代码都可以自动执行时,在代码审查中浪费了很多时间来争论命名,间距,制表符,括号,注释等。甚至有关tableschairs的答案也可以自动化。 LINT'er允许使用字典,每个概念的大写检查(变量,函数,方法,类等)。
即使JavaDoc检查也可以由Robot LINT'er实施,然后才能接受Pull Request。许多开源项目都可以做到这一点。您提交拉取请求,该代码是使用Travis-CI文件(包括静态分析)构建的,并且必须通过所有可以客观表达的编码标准。没有人会抱怨“做错了”或“没有提供评论”,或者用错误的方式命名变量等。这些讨论没有任何价值,最好留给第三方机器人使用,它可以首当其冲。我们要真正回答这个问题,我们就必须解决如何编写一个标准,以解决该问题。以下问题:此评论是否有价值?编码标准不可能规定评论的“值”。因此,人类必须通过该清单。在编码标准中仅提及注释会创建清单,原始海报要避免。
这就是为什么注释通常不由编译器处理并去除的原因。它们的价值无法确定。有关评论是否有价值?是还是不是?。回答这个问题很困难。只有人类有机会正确回答它,即使如此,阅读它的人也只能在阅读时回答它。该评论的价值受天气,他或她的家庭生活,他们刚刚参加的上次会议影响不大,一天中的时间以及所喝咖啡的量的影响。我相信情况会越来越清晰。
如何在任何标准中正确地表达它?除非可以始终如一地公平地应用标准,否则标准将无用。公平是公平,更多的是客观性而非情感。

我认为编码标准应尽可能保持客观性。变量被称为IS目标的方式。可以根据字典轻松地检查它们的正确拼写,语法结构和大小写。除此之外,还有“小便比赛”,由最有力量的人或“眉头殴打”赢得。我个人不做某事感到很苦。如果我在5年后回到此代码,我需要知道什么?什么会有所帮助,哪些会造成混淆,哪些会与代码过时?生成可搜索的公共API的文档代码和为未知的第三方提供价值的注释代码之间有区别,即使该第三方是您自己。
这是一个很好的石蕊测试。如果您是该项目的唯一成员。您知道您将是该项目中唯一的一个。您的编码标准将是什么?您希望您的代码是干净的,自我解释的,并且将来对您自己可以理解。您是否会对自己进行代码审查,以了解为什么没有对每一行都发表评论?您是否会查看在签入的100个文件中创建的每个注释?如果不是,那么为什么要强迫别人?
我相信在这些讨论中遗漏的是,Future You也是该项目的开发人员。在询问价值时,明天的您也是可以从评论中获取价值的人。因此,在我看来,团队规模并不重要。团队经验并不重要,它会经常变化。
没有任何评论代码可以阻止起搏器坠毁并杀死患者。一旦谈论影响代码的注释,您现在谈论的是代码而不是注释。如果只是想写一条谋杀某人的评论,那么过程中还会有其他气味。本身。它与评论无关。评论的问题在于它们对产品最终的工作方式没有影响。嵌入心脏起搏器后,世界上最好的评论无法阻止软件崩溃。或者使用便携式EKG测量电信号时。
我们有两种类型的注释:
机器可读注释
注释样式,例如Javadoc,JSDoc,Doxygen等,都是注释一组代码提供的公共接口的所有方法。该界面只能由其他单个开发人员(两人团队的专有代码),未知数量的开发人员(例如JMS)或整个部门使用。可以通过自动化过程读取此代码,然后该过程将以不同的方式读取那些注释(例如HTML,PDF等)。这是确保每个公共可调用方法,函数,类均包含必需注释的客观过程。标头,参数,说明等。埃尔。这是为了确保另一个团队可以轻松找到并使用该代码。
我正在做一些看起来很疯狂的事情,但实际上并非如此。用一定的方式写。也许正在运行代码的处理器中会出现数字错误,并且总是四舍五入,但是开发人员通常会处理四舍五入的代码。因此,我们发表评论以确保开发人员接触代码后,通常理解为什么当前上下文在做某事通常是不合理的,但实际上是故意写这种方式的。它通常没有注释,后来被新开发人员发现并“修复”。从而破坏了一切。即使这样,评论也只能用来解释为什么不真正阻止任何破坏。
不能依靠评论
评论最终是无用的并且不能被信任。注释通常不会更改程序的运行方式。如果确实如此,那么您的过程会引起更多的问题,而应该这样。评论是事后的想法,只能说什么。代码很重要,因为这就是计算机处理的所有内容。
听起来似乎很愚蠢,但请耐心等待。这两条线中的哪一条真正重要?
// We don't divide by 0 in order to stop crashes.
return 1 / n;
在此示例中,重要的是我们不知道n是什么,没有检查n是否为0,即使存在,也没有阻止开发人员将n = 0放在检查之后0。因此,该评论是无用的,没有任何自动化方法可以解决。没有标准可以捕捉到这一点。评论虽然漂亮(对某些人而言)与产品的结果无关。
测试驱动开发
产品有什么结果?必须严格检查在其中编写代码可以真正保存或杀死某人的行业。这是通过代码审查,代码审查,测试,测试,代码审查,单元测试,集成测试,试用,分阶段,几个月的测试,代码审查和单人试用,分阶段,代码审查,测试来完成的投入生产。注释与此无关。
我宁愿没有注释的代码,没有规范的代码,具有验证规范的单元测试,研究在生产设备上运行代码的结果的代码,然后记录过的代码,从未进行过测试,也没有任何可与之进行比较的代码。
当您试图弄清楚为什么有人以某种方式做某件事时,记录很好,但是,多年来我发现文档通常用于解释为什么做了“聪明”的事情,而实际上并不需要那样写。
结论
如果您在一家需要对每一行都进行评论的公司工作,我保证项目中至少有两名软件工程师已经用Perl,Lisp或Python编写了自动文档程序,该程序确定了该行的工作方式,然后在该行上方添加一条注释。因为这是可行的,这意味着注释是无用的。寻找已经编写这些脚本的工程师来自动记录代码,并以此为依据来证明“每一行的评论”为何浪费时间,没有价值并可能造成伤害。有编程任务的好朋友。他的老师已规定必须记录每一行。因此,我可以看到这种思考过程的来源。只是问问自己,您要做什么,这是对的吗?然后问问自己;有什么办法可以通过这个过程来“游戏”系统吗?如果有,那么它真的增加了任何价值吗?不能自动编写单元测试来测试代码是否符合特定规范,如果可能的话,那也不是一件坏事。人类,确保它不会杀死他们的唯一方法是经过多年的测试,同行评审,试验,然后再也不会更改代码。这就是为什么NA​​SA仍在使用此类旧硬件和软件的原因。当涉及到生死攸关时,您不仅会“做出一点改变并检查一下。”
评论与挽救生命无关。评论是针对人类的,即使编写评论,人类也会犯错。不要相信人类。恩,不要相信这些评论。评论不是您的解决方案。

评论


评论的问题在于它们对产品最终的工作方式没有影响。好吧,如果读写代码的人为因素很重要,我认为确实会影响代码的最终工作方式,但最终代码的执行方式却没有影响。我会说代码的问题仅仅是因为它过时了,然后比没有代码更糟糕!

–迈克尔·杜兰特(Michael Durrant)
16-11-20在21:05

在这里,我们有一个计时员,他想要我们做的每日报告,以便他可以优化我们的工作。无论如何,我们对于每天需要花费15分钟填写他的表格的事实感到有些生气,因此我们通过从日志中填充垃圾来实现自动化。

– joojaa
16年11月20日在21:16

“我们不将0除以阻止崩溃”的注释还有一个额外的问题。语法上尚不清楚“为了”一词是否适用于除法动作或其否定。如果使用“我们避免除以0以...”,则可以避免这种歧义。 :)

–通配符
16-11-23在2:39



“不要为了制止崩溃而除以零”实际上告诉了我很多有关编写它的人的心态。您不编写代码以避免崩溃!您进行编码以使代码正确无误,而不会崩溃只是正确的一小部分。如果要计算的注射药物量最终被零除,那么您将不会返回某些虚拟值,例如99999 ...

–user253751
16年11月23日在5:05

@AndrewTFinnell我的意思是,如果您有时会被零除错误,则添加“ if(divisor == 0)return ; //避免被零除”不会使您的代码更正确。相反,您需要找到除数为何为零的原因并加以解决。设计了一些算法,因此零除数是不可避免的,但是它们是例外(在这种情况下,您可以返回“无法计算结果”的值)。

–user253751
16年11月23日在20:53

#6 楼

在谈论评论时,有两点不同。它们不相同,并且区别很重要。

文档向您介绍一段代码的外向位-其接口。允许您以“独立”方式阅读它们,即您不会同时查看底层代码。

所有接口都应记录在案(例如,每个方法,不包括私有方法) ,并应描述输入,输出以及任何其他期望,限制等,尤其是不能通过约束,测试等表达的内容(确切的数量和去向取决于项目)。 br />
好的文档可以使潜在的消费者决定是否,何时以及如何使用代码。

源代码中的注释具有不同的用途。他们在那里供人们查看源代码。它们主要描述实现。

注释总是在底层代码中读取。 。他们在那里,以便将来的开发人员可以了解其前任的思维过程,并掌握手头的信息,否则他们可能会忽略这些信息或花费大量时间寻求帮助,例如
无法从没有注释的内容中推断出任何内容,并且注释当然可能与周围的代码一样错误,甚至更多。作者和读者都必须做出判断。如果您有一条规则说必须注释每一行,那么您会得到的,但要牺牲重要部分的注释。

但这比这还糟:如果注释了每一行,那么注释的目的就无法实现。注释变得杂乱无章,使代码难以阅读:模糊而不是澄清。此外,不加选择的注释使真正重要的注释更难以发现。

注释和文档都不能提供任何形式的措施或保证来描述它们的代码质量。它们不能代替真正的质量检查。它们的目的是前瞻性的,即希望它们能帮助与之交互的人避免出错。 /方法,但是人类仍然需要检查文档是否有用)。评论是一个判断电话,您的样式指南应该承认这一点。那些从不发表评论的人和那些不加思考地发表评论的人都应该受到挑战。

评论


记录公共API是一个不错的主意,但是我真的很喜欢解释令人惊讶的决定。如果违反至少令人惊讶的原则至少有正当理由,那将是非常好的。 +1

–candied_orange
16年11月21日在6:53

+1表示无关的评论,例如噪音。保持信噪比高。

– sq33G
16-11-21在15:37

如果每一行都被注释,则特别是出于注释目的而+1会失败。太糟糕了,这可能(经常被)用作根本不发表评论的借口,但是由于您提到的原因加上它是正确的,因为如果每一行都被评论,大多数人将自动且可以理解地开始忽略所有评论。

– SantiBailors
16-11-24在8:51

#7 楼

您无法编入注释标准,因为您无法预先知道重要的注释。码。解决方案是要有一个代码审查的标准-要求代码审查对可理解性进行注释。避免使代码难以阅读。并有可能使其变得更好。

这需要一种文化,即代码审查本身并不是毫无意义的手势,将代码以难以阅读的方式发送回是一件好事,侮辱或烦恼。同样重要的是,一个说不清楚的地方并不被视为读者的失败。

在某种程度上,无法阅读的代码是不可避免的。因为作者沉浸在上下文中,并且只有当您知道x,y或z时,才会看到明显的事物。

因此,您将无法制定能够提供良好反馈的规则,但是您可以现场检查评论。甚至非程序员经理也可以这样做-因为真正的问题不是写的代码可读性强,而是代码的可读性,这只能由阅读它的人来决定。

评论


Re您无法编入评论标准-可以。您使注释需要进行代码审查,并且必须指出指出注释未解释代码的代码审查项目。这是一项支出,这是大多数编程环境都不想支付的支出。它在关键软件方面有回报。

–David Hammen
16年11月20日在22:15

“ ...只有当您知道x,y或z时才是显而易见的”您可以指定需要先知道的知识量{x,y,z}才能看到明显的事物,然后机械)),您可以检查当前代码是否成立。在没有的地方,添加注释直到它为止。

– Trilarion
16年11月21日在16:01

@DavidHammen:这不是评论的标准,而是评论的标准。这就是我接下来建议的解决方案。您不能说它一定要有一定的大小,或者必须使用特定的语法,或者甚至首先需要有用的注释(否则您将获得“向i添加一个”类型的注释)。您可以说审阅者必须对代码和评论发表评论。如您所说,您可以要求解决由代码审查引起的问题。但是,要让HAS有责任去做好审稿人。只有审阅者才能判断代码和注释是否足够。

– jmoreno
16-11-22在2:46

@DavidHammen接受评审的人们做出了判断电话?当他们离开时?如果新人们不以相同的方式思考或说英语?如果“审阅者”离开了?您的建议将一些开发人员放在象牙塔的顶部,导致异议,不信任和沟通中断。评论旨在为可以使用它的人们提供见识或澄清。也许乔需要它,但玛丽不需要。当玛丽是审稿人时会发生什么?还是乔?还是马克?

–安德鲁(Andrew T Finnell)
16-11-23在15:59



@jmoreno-不将关于注释的规则/准则放入编码标准中意味着程序员必须查看多个来源-并且他们不知道在哪里查看,直到评论回来说注释不合标准。认为编码标准中的所有内容都必须是自动化的是错误的。例如,有意义的名称规则不是自动的。至少还没有。例如,如果x,y和z或i,j和k可能是非常有意义的名称,如果人们正在基于日记纸实施一种科学算法,该日记纸在其公式中使用了这些名称。

–David Hammen
16年11月23日在16:39

#8 楼

注释每一行代码?否。

您所谈论的其他规则的目的恰恰是避免这种情况。

如果您注释不言自明的整个代码,则在不给出任何其他信息的情况下,您的阅读量将增加一倍。我不确定这种冗余是否会奏效。可以想象一个审阅者说42说“ display_error”,而评论说“显示警告”。但是想象一下代码中的变化。您现在有两个地方要更正。很显然,这种样式具有复制粘贴的底片。相反,如果您对行有疑问,则为:无论是复杂的if还是算法的一部分。 (或者聪明的LINQ单行代码)
如果不能简化它,您将不了解足够的语言成语。 ,但我认为这是一个不错的初始思路。)

鉴于所有这些,甚至有可能编写出能够捕获此想法的良好编码标准?过程。我们的标准对审稿人功不可没。假设它们不是恶意的,这很好用。如果他询问此块是做什么的,请重构或评论。如果有人争论是否清楚,或者审稿人没有弄清,从定义上讲不是。在极少数情况下,很少有朋友会提出类似第二种意见。

平均而言,您应该获得团队中普通程序员可以理解的代码。 IMO保留了多余的信息,并确保至少一个团队的其他成员可以理解该代码,而我们发现这是一个很好的最佳选择。

也没有绝对值。虽然我们是一小群。在5人小组中容易找到共识。

评论


使用代码审查来决定应命名哪些变量,类和方法,这是使人们讨厌公司,企业或方法论的最佳方法。代码审查不应用作强制执行无关紧要的方法。编码标准必须通过自动化过程进行检查。变量名称的长度,圆复杂度,德米特律则可以检查。如果有人告诉我将变量从“ i”重命名为indexForThePreviousCollection之类的东西,我会找到另一个工作场所。值大于3个字符的变量会在自动签入之前进行检查。

–安德鲁(Andrew T Finnell)
16-11-20在20:43



@AndrewTFinnell我无法编写任何您喜欢提及的编程范例中的代码。

–candied_orange
16-11-20在21:25

@AndrewTFinnell好吧,我会礼貌地不同意。 “使用代码审查来决定”,我不知道您是从哪里提取的。在原始作者退出后,我不想在各处使用变量i,j,k编写代码。我不理解您对“人类”基因组的看法。我怀疑是否有一种语言只能声明一个语句,或者很难理解两个语句。正如我所说的,我已经看到了复杂的ifs和LINQ单线。可以用语义上有意义的名称对它们进行注释或重构,我想这就是您的“良好注释”。

–luk32
16-11-20在21:25



@ luk32我尊重不同意的权利。在我看来,迭代变量在上下文中非常明显。在我理解您的发言的情绪的同时,我相信有太多的实践使这种情绪达到了极致。我们是否真的需要读取以下代码:for(int indexForCurrentDatabaseRow = 0; indexForCurrentDatabaseRow
–安德鲁(Andrew T Finnell)
16年11月20日在22:14

我认为名称不应该在代码审查中确定。代码审查通常应该在作者认为足够好之后开始,这也意味着它经过正确注释,易于理解并且变量名称得体。问题是-如果审阅者认为代码太复杂或难以理解变量的含义,那么代码将很难理解。这是没有争议的-显然至少有一个开发人员-审阅者-不理解这一点。是否需要重构(以及如何重构)或正确注释是另一回事。

–伊丹·阿里(Idan Arye)
16-11-20在23:37

#9 楼

问题:


鉴于所有这些,甚至有可能编写出能够抓住这个想法的良好编码标准吗?在同行评审中将是相关的,但不会变成无意识的清单活动,不会产生比以下内容更有用的注释:“您忘记对第42行进行评论”。


评论不应试图对读者进行语言培训。应该假定读者比编写者更了解该语言,但其上下文却比编写者少。

从您的示例开始,该代码的读者应知道exit()将退出应用程序-从而使注释变得多余:

/* Exit the application */
exit();


多余的注释违反了DRY,对代码的更改不一定会传播到注释中,而导致注释无法代码实际上在做什么。

但是,解释您为什么要做某事的注释可能很有价值-尤其是如果您无法轻松地传达代码本身的含义。

Python的PEP 8(CPython标准库中的Python样式指南)为嵌入式注释提供了以下准则:


谨慎使用嵌入式注释。

内联注释是与语句在同一行上的注释。内联
注释应与
语句至少分隔两个空格。它们应以#和单个空格开头。

内联注释是不必要的,并且如果它们声明明显的内容,则实际上会分散注意力。请勿执行以下操作:

x = x + 1                 # Increment x


但是有时候,这很有用:

x = x + 1                 # Compensate for border



给出一个这样的例子,我个人更愿意进一步走下去,并且也会尝试消除这一评论。例如,我可能会得出:

border_compensation = 1
compensated_x = x + border_compensation


使您的代码自我记录并不是一个新主意。

回到实际问题:


鉴于所有这些,甚至有可能编写出能够捕获该思想的良好编码标准?所以是的,我相信这是可能的。

评论


“应该假设读者比作家更懂语言。”我很难相信那是正确的态度。我可以假设他们了解的程度很高,但是每个团队都不一样,团队中的每个人都不一样,因此在这一点上发表笼统的声明似乎并不明智。

–布莱恩·奥克利(Bryan Oakley)
16年11月21日在4:37

没有这个指导,您将让初级程序员提交注释,向他们自己解释琐碎的代码,而中级程序员则使用笨拙的解决方案,只是使初级程序员更容易访问代码。该指南消除了冗余,并确保即使是熟练的程序员也可以继续改进其代码。当我自己重新编写代码时,我可能已经忘记了上下文,但是总的来说,我知道该语言的性能比我第一次编写时还要好。

–亚伦·霍尔
16-11-21在4:50

#10 楼

我想当您看到这种评论时,有时会自己写这种方式,这是因为作者将规范写在评论中,然后遍历并实施每个评论。

面临编写一种编码标准的挑战,该标准产生的代码在其所需功能而非实际功能方面可以理解(这样就可以发现错误),那么我们是否真的在谈论如何定义,记录和链接规范至最终产品?

编辑----

仅作澄清。我没有评论最好的评论vs tdd vs单元测试。还是建议每行添加一个注释是好事还是坏事?

我只是在说一个原因,您可能会看到示例中讨论的注释样式。

质疑有关注释的编码标准是否可以更好地编写为某种规范文档要求。

ie注释用于说明代码的用途,这也是规范的含义

评论


在20年的时间里,我从未见过有人用这种方式注释过他们的代码原型,然后用实际的代码填补了空白。已经有一种客观的方法来实现您所说的或我认为您所说的。这就是所谓的测试驱动开发。单元测试定义规范以及代码是否符合该规范。全部没有评论。

–安德鲁(Andrew T Finnell)
16-11-20在20:04



虽然我认为问题中的代码不是一个很好的例子,但在“代码完成”中专门提到了先在注释中编写一个过程,然后返回并填写代码的做法。帮助生成可读代码的可能做法,@ AndrewTFinnell。这绝对不是闻所未闻的,即使它超出您的经验。

–jscs
16-11-20在20:16



我相信也早于tdd

–伊万
16-11-20在20:28

您是否在谈论伪代码编程过程?这样做的目的是减少评论。我从不记得那本书应该写注释了。评论产生一个概念性的程序意味着高层次的,而不是低层次的。如果要评论他们打算写的每一行,他们可能只是写了几行。这个想法是为了原型出代码的原理而不是每一行。这本书并不建议对每一行都进行注释。这是这个问题的重点。我可能是错的,但我认为那是第二版。

–安德鲁(Andrew T Finnell)
16 Nov 20在20:53



@JoshCaswell&Ewan,是的,它是一种多年前的技术,确实早于TDD。但是,您本应在以后删除评论! TDD已完全取代它,成为创建符合规范的代码的明智方式。

– David Arno
16年11月20日在22:11

#11 楼


鉴于所有这些,甚至有可能编写出能够抓住这一想法的良好编码标准?与同行评审有关但不会变成无意识的清单活动,不会产生比以下内容更有用的注释:“您忘记在第42行发表评论”。


显然,它超出了文档范围-涉及代码的结构,选择的算法等。它甚至可以涉及需求分析和设计。

我的#1规则是“不要记录明显的东西”。 #2规则是“写明显的代码”。

对于安全性至关重要的代码(感谢我,我从来没有做过),这是必要的,但远远不够。甚至可能必须强制要求必须避免使用哪些语言功能(我见过不止一个标准命令“您不得出于任何原因使用scanf( "%s", input );”)。

评论


情人眼中显而易见。并根据截止日期进行更改。

–托尼·恩尼斯(Tony Ennis)
16年11月24日在15:24

#12 楼

自记录代码的最佳实践并不是主流共识-尽管易于理解的代码比隐秘代码更好,这是众所周知的,但并不是所有人都同意是否必须始终重构复杂的代码,或者是否可以发表评论

但是,这场辩论是关于难以理解的代码段-您正在谈论注释每一行代码。难于理解的代码行应该非常少见-如果您的大多数代码行都像这样复杂,那么您将过度使用智能资产一线服务,您应该停下来!当然,有时有时候很难理解某行的角色,但这是它在更大的代码段中的作用-该行本身的作用几乎总是很简单。

因此,您应该而不是注释行-您应该注释代码段。特定的注释可能位于它们所引用的行附近,但是这些注释仍在引用较大的代码。他们没有描述该行做什么/为什么这样做-他们描述了该行代码做什么和/或该代码为什么需要它。

因此,不是应该注释的行,而是更大的行代码段。是否应注释每段代码?否。哈罗德·阿伯森(Harold Abelson)说:“程序必须供人们阅读,并且只能由机器执行”。但是注释仅供人们阅读-机器不会执行注释。如果您的编码标准强制在每行代码/代码段上写多余的注释,那么您不仅在负担需要编写这些注释的开发人员的负担,而且还在负担必须阅读它们的开发人员的负担! >这是一个问题,因为当您阅读的大多数评论都是多余的时,您将停止关注它们(因为您知道它们只是多余的垃圾),然后您将错过重要的评论。所以我说-只写重要的注释,这样当有人在代码中看到注释时,他们就会知道为了理解代码而值得阅读。

评论


错过重要评论:+1。开头的句子:“它们不描述”可以使用一些重组以使其易于理解。

–candied_orange
16年11月21日在2:17

#13 楼

恕我直言,它应该两者兼而有之。评论每一行都是很愚蠢的,因为您最后会看到

  i++;    /* Increment i */


这样的行,而对于为什么要增加i绝对没有任何线索。稍微扩展一下,您将拥有典型的Doxygen注释风格,该注释会产生大量的混乱,而没有提供有关代码用途或工作方式的任何想法。 (至少据我所知:我承认可以使用这样的系统编写有用的文档,但我不屏息。)

OTOH,如果在函数的开头(或任何逻辑分组)写一个好的注释块,描述要完成的事情以及如何(如果不那么明显)有什么用处。如果您是我,您甚至可以包含LaTeX代码以用于相关方程式,或参考论文,例如“这实现了用于解决Hamilton-Jacobi方程的WENO方案,如...所述。”

评论


doxygen注释的+1:这恰恰是我反对在我的代码中包含doxygen“文档”; 95%的时间只是重复了函数签名中已经显而易见的内容。我也没有见过任何值得的doxygen文档。编写这些评论会浪费三倍的时间:一次编写评论,一次再次阅读它们,一次调试由陈旧的评论内容造成的问题。

–cmaster-恢复莫妮卡
16-11-20在22:36

你不是在矛盾自己吗?我想我们都同意,对于函数来说,从黑匣子的角度描述它的功能是至关重要的-“这些输入进入,函数完成,然后这些输出出来”。它形成了编写该功能的人与使用该功能的人之间的契约。 Doxygen的目的仅仅是以一种可解析的方式将这些注释的格式标准化,并使之可搜索/可索引。那么,为什么要一个“好的注释块”,却又不想以一种标准的,人类可读的和机器可读的格式呢?

–格雷厄姆
16年11月23日在13:32

正如@Graham所说,使用诸如JSDoc,JavaDoc和Doxygen之类的注释标准旨在提供可搜索和人类可读的文档。此答案中提到的代码行与Doxygen无关。我什至无法想象有一个规则集可以解析该注释并在输出的文档中产生一个条目。当您查看JMI文档,Java标准库等时,它们都是使用与Doxygen非常相似的工具生成的。这就是它的目的。不是这里所说的

–安德鲁(Andrew T Finnell)
16年11月23日在16:06

我没有对此进行补充-为了满足加拿大的要求,我工作的一家公司让开发人员编写了一个预处理器,该注释与OP的示例完全一样。我认为我们的代码是“向我加1”或类似的代码。它是FORTRAN,因此类似地将循环称为“ C LOOP FROM 1 to 10”。该代码已加载,且无用注释。我在维护代码时删除了所有这些废话。没有人对我说什么。

–托尼·恩尼斯(Tony Ennis)
16年11月24日在15:27

#14 楼

是时候恢复流程图了! (不是真的,但是要等一会儿)

前几天,我找到了旧的流程图模板。我只将它用于家庭作业和笑话(您必须喜欢一个很好的愚蠢流程图)。但是即使到了这个时候,大多数仍在使用流程图的商业程序员仍从代码中自动生成它们(这完全破坏了流程图的初衷,这是编写更好代码的助手,并且在机器代码中非常有用。但是,使用高级语言时,流程图从拐杖变成了霍布勒,为什么?流程图的抽象与代码相同,因此所显示的注释很麻烦,因为它们与代码处于同一抽象级别。好的注释处于与代码不同的抽象级别。做到这一点的最简单方法是使用注释说明代码处理什么的原因;其他方法是将复杂的步骤分解为更简单的替代方法或获得经理级别的抽象。 />

评论


很遗憾地通知您,流程图从未消失。

– Ant P
16-11-20在23:31

好的注释与代码的抽象级别不同。听见!

–candied_orange
16年11月21日在2:45

尽管这可能是不错的建议,但似乎只有一个句子,但似乎并没有解决所提出的问题。

–布莱恩·奥克利(Bryan Oakley)
16-11-21在4:33

#15 楼

我将回答上述问题:


鉴于所有这些,甚至有可能编写出能抓住这一想法的良好编码标准?是。所见即所得。一个好的编码标准从字面上是“对读者清楚以下代码的作用和原因”。

,换句话说,我的代码评论字面意义上的关于代码可读性的1-1是由我的心态


我作为读者(更好的是,作为最低标准,是经验不足但合理的读者的心智模型),不会理解以下代码的目的或工作方法


通常,当人们听到“我,作为高级开发人员,希望您不尊重自己”时,他们很容易加入“这需要更多的可读性”愚蠢,一开始没有读懂这个代码,或者为什么它在那里或做什么,所以需要对其进行解释。 “您的代码具有特定的可读性缺陷,从而导致实际问题”。

需要明确的第二个标准是“凌晨2点紧急测试”。


可以备份吗o不熟悉此代码,请在不带手机的智利安第斯山脉度假时,在凌晨2点紧急生产桥接呼叫中调试该代码时,找出代码的问题? />这听起来可能是主观的,但实际上实际上很容易衡量:召集一个随机的初级团队成员,该成员可能会在生产紧急情况下在夜间进行调试,请他们解释未注释的特定代码如何工作,为什么它在那里。

#16 楼

这个答案涵盖了大多数问题,但是有一件重要的事情。 ,语句,部分,结构,函数,方法,类,包,组件,...代码。


有一些工具可以从代码生成文档,例如例如氧气。如果使用这样的工具,则注释文件,函数,类等是有意义的。即使函数名是自解释的,我仍在这样做是为了保持一致性,因为阅读文档的人们将不胜感激。 >

评论


但是,至少就我的经验而言,由此类工具生成的“文档”通常总比没有文档价值少,因为它无法为用户提供有用的信息(并导致他们浪费时间尝试提取非文档,存在的信息),但愚弄开发人员以为他们已正确记录了他们的代码。

–jamesqf
16-11-22在18:32



@jamesqf是的,当没有记录一半功能时,而另一半则记录得很糟糕。但是,假设开发人员正确地注释了他们的功能,类等,doxygen可以生成非常好的文档。

–BЈовић
16年11月24日在8:45

#17 楼

许多现有的答案都非常详细,但我认为重要的是要回答:


... [评论]与同行评审有关,但不会转变为无意识的清单活动...


对我来说,只有标准的注释可以通过询问缺少的注释来回答。换句话说:IDE或文档软件使用的注释。

这就是说,这取决于开发人员使用的是什么工具,并且并非此类软件使用的所有注释都一样有用。