我的一个同事认为,任何使用代码内注释(即,不是javadoc样式方法或类注释)都是代码的味道。你觉得呢?

评论

我将对任何回答“不”的答案进行投票。

@Renesis那是神性的味道。

您的同事进行了全面概括,这自动表示他错了。 :)

@Mongus,我不同意。您的示例中的注释不好,不是因为它们是注释,而是因为它们太接近代码,然后代码会更改。他们应该说为什么而不是什么。

@Alex,这不是笼统的概括,因此是错误的(导致他无论如何都没有错)?

#1 楼

仅当注释描述了代码在做什么时。

如果我想知道方法或块中正在发生的事情,则可以阅读代码。无论如何,我希望所有从事给定项目的开发人员至少对开发语言足够熟悉,以阅读所写的内容并了解其工作情况。

您可能使用的技术使某人很难遵循您的代码所执行的操作。在这些情况下,注释可以并且应该不仅用于解释为什么要进行这种优化,还可以用于注释代码在做什么。一个好的经验法则是让其他人(或多个其他人)熟悉实现语言和项目来查看您的代码-如果他们既不理解为什么又怎么做,那么您应该同时评论为什么和如何方法。

但是,代码中不清楚的是您为什么要做某事。如果您采用的方法对于其他人来说可能并不明显,那么您应该在注释中说明为什么您做出了自己的决定。我怀疑您可能甚至没有意识到需要注释,直到进行代码审查之类的事情之后,人们才想知道为什么您用X而不是Y-您可以在代码中捕获所有其他查看它的人的答案将来。

但是,最重要的是在更改代码时更改注释。如果更改算法,请确保更新注释,以及为什么使用算法X而不是Y。过时的注释会带来更大的代码味道。

评论


我同意这个答案,但我也看到它被引用为缺乏文档的借口,这是错误的。有时候阅读代码是一件痛苦的事情。您不必查看方法的代码即可弄清楚该方法的作用。您应该能够从名称中找出来,并从文档中获得更多详细信息。阅读代码时,通常必须在一个类与另一个类之间切换,并在一个文件之间切换。这在动态语言中尤其是个问题,在动态语言中编写可以处理所有这些问题的IDE并非易事。

– davidtbernal
2010-09-14的1:48

无论如何,有时候,如果操作起来很复杂(特别是经过优化或任何其他非平凡的操作),您也必须对其进行评论。如果我不得不花超过5分钟的时间来阅读一段代码以了解其功能,那可能会令人沮丧。

– Khelben
2010-09-14 21:46



“仅当注释描述了代码在做什么时。”或者,如果注释描述了代码的用途;代码已更改,但注释未更改。

–布鲁斯·奥尔德曼(Bruce Alderman)
2010年11月11日在22:29

您如何测试您的评论正确?为什么不写您的评论作为测试?任何将来的维护者都可以将测试用作代码的可验证文档。如果注释与代码的执行有关,则必须/ assertable。如果注释与代码的执行无关,那么在仅程序员会看的代码中,注释在做什么?

–烈火企鹅
2010-12-13在16:49

@ back2dos,如果您在阅读别人的代码时经常呕吐,我很高兴我们不共享办公室...

–user1249
2010-12-16 19:57

#2 楼

此刻听到的消息特别令人不快,我这个周末花了一些时间,看了一个非常有名,非常干净,没有注释的实现研究算法的代码(实际上并没有发布过)。我对此非常熟悉,坐在我旁边的那个人是发明家,而代码是几年前由其他人编写的。我们几乎不能跟随它。

您的同事显然经验不足。

评论


我很好奇地看一看很难理解的“名字很好,很干净,没有注释的代码”。我将其归为此类的任何代码都非常容易遵循。我当然不会说“显然您的同事经验不足”。

– Liggy
2010-09-15的1:34

@Liggy:我会的。这是一种研究算法,而不是业务线应用程序。

– Paul Nathan
2010-09-15 17:14

我曾经有一段代码,您必须按照“错误”顺序(由过程的“逻辑”和我们的编码标准定义)来填充数据库列对象(第三方)中的字段-按照我们通常会使用,它会崩溃。没有足够的代码阅读量可以告诉您这一点,因此,绝对肯定地,必须要有注释-这不是一种气味,至少在我们控制的代码中(这是底线)没有。完全和完全缺乏评论与不良评论一样有异味。

–墨菲
2010-09-27在7:28

数学,数学,数学。并非所有代码都实现了琐碎的IoC粘合和“价格*数量”。复杂的数学无法神奇地自我解释。

– bmargulies
2010-10-1 23:06

@Liggy,如果没有大量文档,实现复杂数据结构的代码将是完全难以理解的。

–user1249
10-10-4在6:44

#3 楼

注释应该说明原因,而不是原因。
How类型注释通常可以使用重构更好地处理。就我个人而言,我通常避免评论,而倾向于重构。

之前:

# convert to cents
a = x * 100

# avg cents per customer 
avg = a / n

# add to list
avgs < avg
t += 1


之后:

br />

评论


我同意为什么不这样做,并且您的重构在此示例中起作用,但是对于更复杂的代码,没有任何数量的变量/函数重命名/重构会很有意义,并且在那里仍然需要注释。

–GSto
2010年9月9日在2:09

很好的例子,但是为什么系统使用美分而不是美元呢?这个问题在金融系统中变得很重要,您可能会看到小数货币发挥作用。

– rjzii
2010-12-15 14:07

@Stuart函数的名称应说明其功能。

– Alb
2011年1月31日,12:19

@GSto,我完全同意。如果代码很复杂,则应将其分解为较小的方法/函数,并使用适当的名称来描述操作。

–CaffGeek
2011年2月4日在5:49

您假设已经完全控制了代码库。

– LennyProgrammers
2011年2月8日14:13在

#4 楼

我宣布你的同事是异端!我的异端燃烧靴子在哪里?

过分的注释是不好的,而且维护起来很头疼,注释不能替代名称明确的方法,类,变量等。但是有时要说明为什么对于必须在六个月内维护代码的可怜白痴来说,这可能是非常有价值的-尤其是当那个可怜白痴最终成为您时。

我正在研究的代码中的一些实际注释上:


    // If this happens, somebody's been screwing around with the database definitions and
    // has removed the restriction that a given alarm may have only one entry in the 
    // notifications table.  Bad maintenance programmer!  Bad!  No biscuit!



    // If an alert is active on our side but inactive on theirs, that might mean
    // they closed the alert.  (Or that we just haven't told them about it yet.)  The
    // logic comes later; for now, we'll just compile it in a list.



    // If we know for a fact that an alarm isn't getting through, we're going to whine pretty
    // aggressively about it until it gets fixed.



评论


+1为好评论。没有大量的代码可以说“如果发生这种情况,那就是有人在搞乱数据库定义”。

–DistantEcho
2010-11-24 14:37

@Niphra,好吧,我们可以抛出SomebodyScrewedAroundWithDatabaseException ...

–user1249
2010-12-15 22:32

@Thorbjørn+1,如果代码知道出了什么问题,那就报告一下。客户支持技术人员可能会重新加载数据库,并避免了服务呼叫。

–蒂姆·威利斯克罗夫特(Tim Williscroft)
2010-12-15 22:42

@Tim,正如客户可能看到的那样,更中性的命名可能是合适的。

–user1249
2010-12-15 23:26

当然,请记住:永远不要使用愚蠢的名字。客户将始终看到它们。

–蒂姆·威利斯克罗夫特(Tim Williscroft)
2010-12-15 23:28

#5 楼

理想情况下,代码应该被很好地编码,以使其具有自动解释性。在现实世界中,我们知道有时也需要注释非常高质量的代码。

您绝对应该避免的是“注释代码冗余”(注释不添加任何代码): br />
i++; // Increment i by 1


然后,如果有一个好的(并且保持/对齐的)代码设计和文档,那么注释就没有用了。环境注释可以帮助提高代码的可读性:

while( foo )
{
     if( dummy )
     {
     }
     else // !dummy
     {
     }
} // end while( foo )


别忘了您还必须保持并保持同步,同时注释...过时或错误的注释可能会很痛苦!而且,通常,注释过多可能是不良编程的征兆。

评论


好的命名约定和结构良好的代码将帮助您减少注释的需要。不要忘记,您添加的每一行注释都是要维护的新行!!

–加布里埃尔·芒贡(Gabriel Mongeon)
2010年9月1日19:47

我讨厌人们在您的问题中使用第二个例子。 } // end while仅表示while循环的起点距离如此遥远,您甚至看不到它,也没有暗示您正在查看的代码处于循环中。对于代码的结构注释,应该优先考虑使用重重构。

–卡森·迈尔斯(Carson Myers)
2010年9月1日于20:03

@Carson:虽然使代码块简短是一个众所周知的规则,但这并不意味着我们总是可以应用它。

–Wizard79
2010年9月1日于20:15

@Carson:我从事的项目之一没有足够的代码审查,这导致了一系列JSP的循环复杂性“ OMFG只是杀死了你自己”。重构血腥的事物代表着需要在其他地方花费的工作日。 } //结束,而注释可以节省生命。

– BlairHippo
2010-09-2 15:26

@BlairHippo:“ [A]代码气味是程序源代码中的任何症状,可能表明存在更深层的问题”。当然,注释是挽救生命的,但是OMGWTF循环是前面提到的“更深层次的问题”,挽救生命的必要性是一个明确的指标;)

–back2dos
2010-09-12 18:10

#6 楼

将方法或过程分类定义为“代码气味”是“狂热气味”。该术语正在成为新的“被认为是有害的”。

请记住,所有这些事情都应该作为指南。

许多其他答案也都提供了很好的建议关于何时需要发表评论。

我个人很少使用评论。说明非显而易见的过程的目的,并将偶然的死亡威胁留给可能正在考虑自己进行更改并需要数周调整的任何人。

重构所有内容,直到幼儿园可以理解为止

注释不会影响运行时间,因此唯一需要考虑的负面问题就是维护。
/>

评论


我认为“反模式”是新的“被认为有害”。代码气味只是需要仔细检查以进行可能的清理的东西。

– Jeffrey Hantin
2010-10-7 20:58

我不同意反模式也可以胜任。当设计足够复杂以至于显然是一个故意的选择时,它们都以反模式代替气味的方式被使用。无论哪种情况,我都不同意在这些事情上有绝对正确的来源的概念。

– Bill
2010-10-8 1:06

+1表示“重构所有内容,直到幼儿园老师可以理解为止,这可能并不能有效地利用您的时间,并且可能不会表现得更简洁。”

–埃尔兹
2011年2月19日5:00

#7 楼

这里的主要问题是“代码气味”一词的含义。

许多人(我认为包括您在内)都将代码气味理解为接近错误的东西,或者至少需要某种东西来理解。是固定的。也许您将其视为“反模式”的同义词。

这不是该术语的含义!

代码气味隐喻源自Wards Wiki,并且他们强调:


请注意,CodeSmell暗示某些事情可能是错误的,而不是确定性。完美的习惯用法可能被认为是CodeSmell,因为它经常被滥用,或者因为有一种更简单的替代方法在大多数情况下都可以使用。调用CodeSmell并不是攻击。这只是一个迹象,表明必须仔细看一下。 :“嗯,我觉得有一些可以改进的提示”。也许您可以重命名变量,执行“提取方法”重构-也许注释实际上是最好的解决方案。

这就是注释成为代码味道的含义。

编辑:
我只是偶然阅读了这两篇文章,这对我来说比它更好地解释了:



代码中的道歉
需要评论


评论


我很惊讶,这个答案花了两个月的时间。它表明了对该术语的误解有多普遍。

–Paul Butcher
2011-2-10在10:17

一般情况的断言仍然是错误的。您不会说:“我看到的是注释代码。这是一个不好的信号。”

– Stuart P. Bentley
2011年5月30日7:37



@Stuart:您正在查看两个代码块,每个代码块都有适当的注释级别。 (此问题与注释的适当数量无关,而与基于注释数量判断代码的方式有关。)一个没有注释,另一个没有注释。您更看哪一个? -注释表明代码复杂而微妙,因此更有可能出现问题。

– David Schwartz
2011年9月7日13:59



这是正确的答案。

– vidstige
2012年2月27日15:39

#8 楼

在某些情况下,好的命名,重构等方式都无法替代注释。看看这个真实的例子(语言是Groovy):

  response.contentType="text/html"
  render '{"success":true}'


看起来很奇怪,不是吗?可能是复制粘贴错误?哭了一个错误修复程序吗?

现在与注释相同:

  // DO NOT TOUCH THE FOLLOWING TWO LINES; the ExtJS UploadForm requires it exactly like that!!!
  response.contentType="text/html"  // must be text/html so the browser renders the response within the invisible iframe, where ExtJS can access it
  render '{"success":true}'         // ExtJS expects that, otherwise it will call the failure handler instead of the succss handler


评论


函数prime_extjs_uploadform(){response.contentType ='text / html';渲染'{“ success”:true}'; } prime_extjs_uploadform();

– DrPizza
2012年9月4日5:27



#9 楼

我认为规则很简单:想象一个完全陌生的人看到您的代码。您可能会在5年后成为自己的代码的陌生人。
请尽量减少为理解该陌生人的代码而付出的精力。

评论


+1对于尚未在单个项目上工作过足够长的经验才能体验到这一点的开发人员,请相信我会成功的。每当我以这种艰苦的方式学习并不得不重新学习自己的代码时,我就不会让自己犯两次相同的错误并在继续进行其他操作之前先对其进行注释。

–妮可
2010-09-17 20:33

不,您应该想象一个精神病患者知道您的住所:他们会乐于维护您的代码吗?

–理查德
2010-09-27 9:54



当我看到不可读的代码时,我经常会变态。

– LennyProgrammers
2010-09-27 12:32

5年?大约5分钟。 ;)

– Alex Feinman
2010-10-21 16:50

#10 楼

拥有正确注释的一个好主意是从编写注释开始。

// This function will do something with the parameters, 
// the parameters should be good according to some rules.
myFunction(parameters)
{
    // It will do some things to get started.

    // It will do more with the stuff.

    // It will end doing things with the stuff.
}


这可以使您轻松提取方法甚至摆脱注释,让代码告诉这些事情!以一种非常不错的方式查看如何重写(剪切/粘贴):

// This function will do something with the parameters, 
// the parameters should be good according to some rules.
myfunction(parameters)
{
  var someThing = initializedWithSomething;

  doSomethingWith(someThing);

  doMoreWith(someThing);

  endDoingThingsWith(someThing);

  return someThing;
}

// This function will do some things to get started,
// the parameters should be good according to some rules.
doSomethingWith(parameters)
{
  parameters.manipulateInSomeWay();
  ... etc ...
}

... etc ...


对于无法分离的事物,请不要提取方法并键入注释下的代码。

这是将注释保持在最低水平的一种有用方法,去注释每一行真的没用。值初始化或有意义的初始化。

如果参数使用过多,则它们应该是您的类中的私有成员。

评论


这就是我所做的。如果您认为需要评论,我可以建议您尝试一下。

– bzlm
2010-09-16在7:15

#11 楼

我认为答案是通常的“取决于”之一。仅仅为了注释代码而注释代码是一种气味。注释代码是因为您使用的模糊算法的速度快一个数量级,因此可以节省维护程序员(通常是我在编写代码后的6个月内),以节省半天的时间来确定代码的工作方式。

#12 楼

// Dear me in the future. Please, resolve this problem.




// You think this code was written by somebody else. 
// No, it wasn't. You ([some name]) did it.


评论


啊,衷心请未来的自己。

–安东尼·佩格拉姆
10-10-1在15:28

#13 楼

代码注释绝对不是“代码气味”。这种信念通常来自这样一个事实,即评论可能会过时(过时)并且难以维护。但是,具有良好的注释可以解释为什么代码以某种方式做某事对于维护而言很重要(通常如此)。


良好的注释使您更容易理解
代码正在做,并且
更重要的是为什么要以特定的方式来做。注释应供程序员阅读,并且应清晰,准确。
难以理解或不正确的注释与
根本没有任何注释
相比要好得多。 />您的代码意味着您不必
依靠内存来理解一段代码的“什么”和“为什么”。
当您查看时,这是最重要的
稍​​后再使用该代码,否则其他人必须查看您的代码。因为
注释成为代码文本内容的一部分,所以它们应该
遵循良好的写作原则,并且要清晰易懂。


写一个很好的评论,您应该做的最好。
记录下代码的用途(为什么,而不是如何),并
指出推理和逻辑
在代码后面尽可能清晰地
。理想情况下,注释应该在编写代码的同时
编写。如果您等待,您可能
不会回去添加它们。

Sams在24小时内自学Visual C#2010,第348-349页。

评论


注释可能会过时,但是对于未经编译器或单元测试验证的所有内容,例如类,函数和变量名的含义,都是如此。

– LennyProgrammers
2010-09-10 8:39

@ Lenny222:是的,注释可能会过时...这通常表示懒惰的程序员。如果注释描述了为什么进行决策,代码为何使用特定算法进行计算或描述了代码如何运行,那么除了有人更改了实现并没有相应更新注释之外,没有其他理由使注释变得陈旧。 -等同于懒惰。

–斯科特·多曼(Scott Dorman)
2010-09-10 15:22



我同意。我的意思是,它有可能过时,是的。但是,当我有一个函数doBar()并在3年后不再“做bar”,而是“除了星期三之外就做bar和foo”时,函数的含义也会过时。和变量名。但是,我希望没有人因为没有给函数和变量赋予有意义的名称的原因。

– LennyProgrammers
2010-09-10 15:25

#14 楼

如果以某种特殊的方式编写了代码,以避免出现库(第三方库或编译器随附的库)中存在的问题,则可以对其进行注释。
也例如,注释需要在将来版本中更改的代码,或者在使用库的新版本时,或者从PHP4传递到PHP5时,注释的代码。

#15 楼

即使是写得最好的书,也很可能会有引言和章节标题。记录良好的代码中的注释对于描述高级概念以及解释代码的组织方式仍然很有用。

评论


这种注释提供了很好的视觉提示,因此您不必阅读每一行即可找到所需部分的开头。就像我祖父曾经说过的:“一切都要适度”。

– Blfl
2011-11-25 14:24

#16 楼

值得一提的是反模式:

我的印象是,有时会经常使用FLOSS许可证的示例来代替文件文档。 GPL / BSDL很好地填充了文本,之后您几乎看不到其他任何注释块。

#17 楼

我不同意写注释来解释代码的想法不好。这完全忽略了代码存在错误的事实。可以很清楚地看到代码没有注释的作用。不太清楚代码应该做什么。如果没有注释,您如何知道结果是否错误或使用不正确?

注释应解释代码的意图,以便如果有错误,请有人阅读注释+代码可以找到它。

我通常会在编写代码之前先写内联注释。这样一来,我就可以清楚地知道我正在尝试编写代码来做的事情,并减少了在算法中不会真正知道自己要做什么的迷路。

评论


单元测试有助于确定结果是否错误。如果您读了一些代码并认为实际上是X,那么实际上是X,那么代码可能没有以足够可读的方式编写。我不确定您对错误使用结果的意思。注释不能防止您以奇怪的方式使用代码。

–亚当·李尔♦
2011-2-27在15:36

“如果您阅读一些代码,并认为实际上它会执行X,那么实际上它会执行Y”,这不是我所说的。我说的是了解代码的作用,而不是代码的作用。假设您怀疑一个错误。您如何知道一次性代码错误不在使用代码中,也不在此代码中?注释解释了代码的意图,这对跟踪错误有很大帮助。

– Danny Tuppeny
2011-2-28在6:55

另一方面,注释可能只告诉您在编写注释时代码应该做什么。代码本身可能会告诉您现在应该做什么。注释不编译。您无法测试评论。它们可能正确也可能不正确。

–安东尼·佩格拉姆
11年8月23日在21:13

#18 楼

因为有人认为可以在一种方法中包含700行是有异味,所以提出评论。

这里的评论是因为您知道如果不发表评论,则有人会做出同样的错误又是一种气味。

之所以加入注释,是因为某些代码分析工具要求它也是一种气味。

永远不会发表评论的人,甚至为其他开发人员写一点帮助也有异味。令我惊讶的是,有多少人没有写下来,但随后他们转身承认他们不记得三个月前的所作所为。我不喜欢写文档,但是我不得不一次又一次地告诉人们同一件事。

#19 楼

我会自己回答一个问题。您可以在下面未注释的代码中找到该错误吗?

tl; dr:下一个维护您代码的人可能不像您那样虔诚。

 [org 0x7c00]

 main:
  mov ah, 0x0e
  mov bx, string
  call strreverse
  call print

 stop:
  jmp $

 strreverse:
  pusha
  mov dx, bx
  mov cx, 0

 strreverse_push:
  mov al, [bx]
  cmp al, 0
  je strreverse_pop
  push ax
  add bx, 1
  add cx, 1
  jmp strreverse_push

 strreverse_pop:
  mov bx, dx

 strreverse_pop_loop:
  cmp cx, 0
  je strreverse_end
  pop ax
  mov [bx], al
  sub cx, 1
  add bx, 1
  jmp strreverse_pop_loop

 strreverse_end:
  popa
  ret

 print:
  pusha

 print_loop:
  mov al, [bx]
  cmp al, 1
  je print_end
  int 0x10
  add bx, 1
  jmp print_loop

 print_end:
  popa
  ret
 string:
  db 'Boot up', 0

 times 510 -( $ - $$ ) db 0
 dw 0xaa55


评论


但是,在当今时代,您是否不使用高级语言?

–伊恩
2011年2月8日在14:11

@Ian:该程序是IBM-PC引导程序。您不能用汇编以外的任何方式编写它,因为您需要完全控制程序在RAM中的位置,最后一个短路出现的位置以及某些硬件中断。认真地,给自己买一份NASM。组装它,将其写入软盘或USB记忆棒的引导扇区,然后引导它。尽管您可能会发现由于该错误,它无法按预期工作。现在查找错误...无论如何,我敢肯定,从现在开始的20年后,人们会问同样的问题,即未注释的Java。

–蚂蚁
2011-2-8 15:02



可以肯定的是,代码可以用C或C ++编写,而二进制文件则由C对象代码和一些外部工具汇编而成。

–kevin cline
2011-3-22在23:03

不幸的是没有。在CodeProject上查看以下页面:codeproject.com/KB/tips/boot-loader.aspx-“高级语言没有必要的说明”。不仅如此,在引导加载程序中您只有512个字节可以使用。有时,您只需要直接使用硬件即可。

–蚂蚁
2011-3-23在9:29

在编写汇编代码时,我会做其他所有人都会做的事情-在每一行中注释其正在做的事情。问题所在的行将带有注释“检查字母是否为0”,因为代码使用C样式的0终止字符串。有了该注释,就很容易看到代码正在使用1执行cmp,这意味着它要么陷入无限循环,要么打印垃圾,直到它在RAM中达到随机1。我可能还添加了有关字符串以0结尾的事实的注释,这在代码中并不明显。是否有用于汇编代码的自动化单元测试之类的东西?

–蚂蚁
11年5月20日在11:47



#20 楼

您必须在代码和注释之间保持平衡...通常,我会尝试添加一些可恢复代码块的注释。不是因为我无法理解代码(嗯,也是),而是因为我可以更快地阅读自己的代码,并在发生重大事件的地方找到特定的部分。

无论如何,我的自己的个人标准是“有疑问时发表评论”。我宁愿使用冗余线,也不愿使用完全无法理解的完全隐秘的线。一段时间后(我通常会这样做),我总是可以删除代码审阅中的注释。

此外,添加“ caveats”(例如,“小心!如果输入格式不正确),注释也很有帮助。 ASCII,此代码必须更改!“

评论


您能解释一下“恢复一段代码的注释”的意思吗?

– Mark C
2010-11-23 5:23

#21 楼

读此书时,我想起了几十年前我第一次读到的东西(从更长的列表中保留下来,通过影印保留):


真正的程序员不会写评论-如果很难的话写起来应该很难读


比较老的气味方法。

#22 楼

我认为代码注释起步很糟糕。这些天我不知道,但是当我第一次在学校学习编程时,我得到了“编写一个在单独的行上打印数字1到10的程序。请确保对代码进行注释”的本质。如果您不添加注释,则会被打倒,因为注释您的代码是一件好事。

但是,对于这样一个微不足道的过程有什么要说的呢?因此,您最终写了经典的文章

i++; // add one to the "i" counter.


只是为了获得一个不错的成绩,并且,如果您有任何疑问的话,立即对代码注释的看法会很低。

代码注释不是一件好事。这是有时必要的事情,而在最上面的答案中的托马斯·欧文斯(Thomas Owens)提供了对必要情况的很好的解释。但是,这些情况很少会出现在作业类型的作业中。

从很多方面来说,添加注释应该被视为最后的选择,而在活动中无法明确地说出需要说的话编程语言的一部分。尽管对象命名可能会过时,但是各种人为和计算机缺乏反馈的机制使忘记维护注释变得容易,因此注释比活动代码更快地过时。因此,在可能的情况下,始终应该选择更改代码使其更清晰,而不是使用注释注释不清晰的代码。

评论


+1指出不良的评论习惯始于早期的编程课程。结论为-1是不得已的选择。

– AShelly
10 Nov 17 '21:43

#23 楼

当然,注释是代码的味道...

每个程序员都知道,由于工作量,调试或我们碰到的疯狂,我们最终都会变得疯狂。

“这样做!”您的项目经理说。

您回答,“这不可能完成。”

他们说,“那么我们会找其他人去做。”
/>
你说,“好吧,也许可以做到。”

然后花下X天,..周..个月..来弄清楚。在整个过程中,您将尝试失败,并且尝试失败。我们都这样做。真正的答案是有两种类型的程序员,一种是注释的,另一种是不注释的。

1)这样做的目的是通过记录以备将来参考,注释掉不起作用的失败例程,从而使自己的工作变得更加轻松(找到合适的例程后,气味并没有删除它们)。 ,或使用注释格式对代码进行分解,以期使其更易于阅读或理解。说真的,我不能怪他们。但最后,它们会折断,然后您就会得到:
// dammit this code sucks! swear! curse! i hate it! i am going to write something here to vent my anger!!!!

2)那些不装做超级英雄或住在山洞里的人。他们只是鲁re地无视他人,他们可能不太在乎代码,或者以后可能有什么含义。

现在不要误会我..自文档化的变量和函数可以完全避免这种情况..相信我,您永远无法进行足够的代码清理。但简单的事实是,只要保留备份,就可以始终删除评论。

评论


响应1.在注释例程中,真正的气味不是在您确定它们可能是死胡同并想尝试其他方法时不会立即删除它们-这是因为如果您决定重新访问它们,则它们应该在版本控制中可用。

–夏皮
2011年1月10日,0:12

#24 楼

我认为在代码中不使用一些注释是一种代码味道。虽然我同意代码应该尽可能地自我记录,但是您遇到了某个问题,无论代码编写得如何好,您都会看到毫无意义的代码。我已经在业务应用程序中看到一些代码,其中的注释几乎是强制性的,因为:


您需要根据情况做一些事情,并且没有很好的逻辑。
更改法律后,您可能会在一两年内更改代码,而您想迅速找到它。
过去有人编辑了代码,因为他们不了解代码在做什么。

另外,公司样式指南可能会告诉您以某种方式做某件事-如果他们说您应该有注释,概述函数中正在执行的代码块,然后添加注释。

#25 楼

注释和代码之间存在很大的根本区别:注释是人们与他人交流思想的一种方式,而代码主要是用于计算机的。 “代码”中有许多方面也只适用于人类,例如命名和缩进。但是评论是严格由人类编写的。

因此,编写评论与任何书面交流一样困难!作者应该清楚地了解谁是受众,以及他们需要什么样的文本。您怎么知道谁会在十年,二十年后阅读您的评论?如果此人来自完全不同的文化怎么办?等等,我希望每个人都能理解。

即使在我所居住的同质小文化中,也很难与他人交流思想。人为交流通常会失败,除非是偶然的原因。

#26 楼

我必须同意你的同事。我总是说,如果我注释我的代码,这意味着我担心将来无法弄清楚自己的代码。这是一个不好的信号。

我向代码中添加注释的唯一其他原因是要调用似乎没有意义的内容。

这些注释通常需要形式如下:

//xxx what the heck is this doing??




// removed in version 2.0, but back for 2.1, now I'm taking out again


评论


或者,也可以在注释中反映以下事实:代码正在处理一种复杂的算法,在这种算法中,代码本来就变得不明显,或者由于代码超出了您的控制范围(例如,与外部服务进行交互)而使代码做得有些奇怪。

–墨菲
2010-09-27在7:37

非常真实有很好的代码可能并不明显的原因。尽管在大多数情况下,令人困惑的代码是令人困惑的,因为它们是以混淆的方式编写的。

–肯
2010-09-29 16:56

似乎您还没有为只有32k的嵌入式处理器编写代码,而这确实使您望而却步。评论是救命稻草。

–quickly_now
2011年1月31日上午9:21

#27 楼

在适当的地方提供函数自变量和返回值,结构字段甚至局部变量的代码注释会非常方便。记住火星轨道器!

评论


将这些单元构建为变量名称要好得多,因此可怜的程序员不必记住它们。而不是'double length // in meter',而不是'double length_m'。最棒的是使用一种更强大的语言,因此您可以简单地说:力f;扭矩t = l * f;打印(t.in(Torque.newtonMeter));

–kevin cline
2011-3-22在23:00

#28 楼

这是我的经验法则:


编写代码并将代码的简短摘要存储在单独的文档中。
将代码单独放置几天以进行处理其他。
返回代码。如果您无法立即了解它的功能,请将摘要添加到源文件中。


#29 楼

向您的同事介绍Literate编程技术。

#30 楼

不,注释不是代码的味道,它们只是可以滥用的工具。

好的注释示例:需要进一步调查!

//这是执行X的聪明方法

//此处的列表保证为非空

评论


第三个是IMO的不好评论。为什么不断言(list.IsEmpty)?

– CodesInChaos
2012年2月6日在12:51

@CodeInChaos IMO Assert(!list.isEmpty())与第三条注释中的约定并不完全相同,只是行为(即“如果参数为空则抛出IllegalArgumentException”),必须像其他程序逻辑一样进行单元测试。注意注释的细微差别,该注释指出何时可以使用该方法,但是如果不满足前提条件,则不指定任何行为。比评论更好的是执行编译时合同。但这超出了我的回答的范围;)

– Andres F.
2012年2月23日在1:41



您不应该练习Asserts,因为它们描述了永远都不会发生的事情,即使公共API接收到无效的参数也是如此。

– CodesInChaos
2012年2月23日在8:48

@CodeInChaos我撤回我的意见。这是Sunacle关于断言的说法。看来你是对的。好吧,你每天都学到一些东西!

– Andres F.
2012-02-23 13:28