我们都知道,对我们的代码进行评论是编码风格的一个重要部分,可以使我们的代码可以理解为下一个人,或者甚至是我们在6个月左右的时间.
然而,有时评论只是没有削减芥末.我不是在谈论明显的笑话或排泄沮丧,我说的是那些似乎试图解释的评论,但这样做很差,他们可能也不会在那里.评论太短,太神秘,或者只是完全错误.
作为一个故事,你能否分享你所看到的那些真的那么糟糕的东西,如果不是很明显,请展示它所指的代码并指出它有什么问题?什么应该在那里,而不是已经走了吗?
也可以看看:
什么时候不评论您的代码
你觉得怎么样?(最佳实践)
您遇到的源代码中最好的评论是什么?
Rich Bradsha.. 112
只是典型的Comp Sci 101类型评论:
$i = 0; //set i to 0 $i++; //use sneaky trick to add 1 to i! if ($i==$j) { // I made sure to use == rather than = here to avoid a bug
诸如此类的事情.
只是典型的Comp Sci 101类型评论:
$i = 0; //set i to 0 $i++; //use sneaky trick to add 1 to i! if ($i==$j) { // I made sure to use == rather than = here to avoid a bug
诸如此类的事情.
未填充的javadoc样板评论特别无用.他们消耗了大量的屏幕空间而没有贡献任何有用的东西.最糟糕的是,如果出现这样一个评论,其他数百个肯定会潜伏在其中.
/** * Method declaration * * * @param table * @param row * * @throws SQLException */ void addTransactionDelete(Table table, Object row[]) throws SQLException {
我之前发现自己写的这个小宝石:
//@TODO: Rewrite this, it sucks. Seriously.
通常这是一个好兆头,我已经到了我的编码会议结束了一夜.
// remember to comment code
跆拳道?:d
像这样的东西:
// This method takes two integer values and adds them together via the built-in // .NET functionality. It would be possible to code the arithmetic function // by hand, but since .NET provides it, that would be a waste of time private int Add(int i, int j) // i is the first value, j is the second value { // add the numbers together using the .NET "+" operator int z = i + j; // return the value to the calling function // return z; // this code was updated to simplify the return statement, eliminating the need // for a separate variable. // this statement performs the add functionality using the + operator on the two // parameter values, and then returns the result to the calling function return i + j; }
等等.
每一条只重复代码所说的评论都是无用的.评论不应该告诉我代码的作用.如果我不太了解编程语言,只需阅读代码就能理解正在发生的事情,我根本不应该阅读那些代码.评论喜欢
// Increase i by one i++;
完全没用.我看到我增加了一个,这就是代码所说的,我不需要对此进行评论!应该使用注释来解释为什么某些事情已经完成(如果它远非显而易见)或者为什么某些事情是以某种方式完成而不是以任何其他方式完成(因此我可以理解另一个程序员所做的某些设计决策,这些决策到目前为止并不明显)一旦).进一步的注释对于解释棘手的代码很有用,因为通过快速查看代码绝对不可能确定发生了什么(例如,有一些棘手的算法可以计算数字中设置的位数;如果不是知道这个代码做了什么,你没有机会猜测那里发生了什么.
Thread.Sleep(1000); // this will fix .NET's crappy threading implementation
我曾经在一个带有奇怪的C编译器的项目上工作过.除非在两个语句之间插入注释,否则它会对有效代码产生错误.所以我把评论改为:
// Do not remove this comment else compilation will fail.
而且效果很好.
我不相信.在得到22个答案之后我才提出这个问题,没有人指出最不可能有用的评论类型:
评论错了.
人们编写多余的评论会妨碍理解代码,但当有人撰写详细的评论来解释某些内容是如何工作的时候,这是错误的,并且首先是错误的,或者在更改代码而不更改评论后更改错误(更可能的情况),这绝对是最糟糕的评论.
GhostDoc自己提出了一些非常有趣的东西.
////// Toes the foo. /// ///public Foo ToFoo()
// secret sauce
// Don't know why we have to do this
try { ...some code... } catch { // Just don't crash, it wasn't that important anyway. }
*叹
遇到过一次文件.成千上万的代码行,其中大部分代码都非常可怕.错误命名的变量,循环上的棘手条件和埋在文件中间的一条注释.
/* Hmmm. A bit tricky. */
//' OOOO oooo that smell!! Can't you smell that smell!??!??!!!!11!??/!!!!!1!!!!!!1 If Not Me.CurrentMenuItem.Parent Is Nothing Then For Each childMenuItem As MenuItem In aMenuItem.Children do something Next If Not Me.CurrentMenuItem.Parent.Parent Is Nothing Then //'item is at least a grand child For Each childMenuItem As MenuItem In aMenuItem.Children For Each grandchildMenuItem As MenuItem In childMenuItem.Children do something Next Next If Not Me.CurrentMenuItem.Parent.Parent.Parent Is Nothing Then //'item is at least a grand grand child For Each childMenuItem As MenuItem In aMenuItem.Children For Each grandchildMenuItem As MenuItem In childMenuItem.Children For Each grandgrandchildMenuItem As MenuItem In grandchildMenuItem.Children do something Next Next Next End If End If End If
IDE插入的默认注释.
我使用WebSphere Application Developer的最后一个项目有很多维护开发人员和承包商,他们似乎并没有被数百个(如果不是数千个)包含以下内容的Java类所困扰:
/** * @author SomeUserWhoShouldKnowBetter * * To change this generated comment edit the template variable "typecomment": * Window>Preferences>Java>Templates. * To enable and disable the creation of type comments go to * Window>Preferences>Java>Code Generation. */
在认为你实际上找到一个评论良好的源文件并意识到这一点之间总是存在分秒,是的,这是另一个默认评论,它迫使你使用SWEAR_WORD_OF_CHOICE
.
我昨天在C#应用程序中看到了这条评论:
//TODO: Remove this comment.
我最喜欢的评论.
/* our second do loop */ do {
谁写了 - 你知道你是谁.
许多年前C中的一个非常大的数据库引擎项目 - 数千行代码,包含短的和拼写错误的变量名,没有注释......直到嵌套if条件深入到模块中的数千行,出现以下注释:
//if you get here then you really f**ked
到那个时候,我想我们已经知道了!
在一个巨大的VB5应用程序中
dim J J = 0 'magic J = J 'more magic for J=1 to 100 ...do stuff...
引用显然是这个 ......是的,没有这两行的应用程序在运行时因未知的错误代码而失败.我们仍然不知道为什么.
取自我的一篇博文:
在清理我管理的一个项目的一些源代码的过程中,我发现了以下注释:
/* MAB 08-05-2004: Who wrote this routine? When did they do it? Who should I call if I have questions about it? It's worth it to have a good header here. It should helps to set context, it should identify the author (hero or culprit!), including contact information, so that anyone who has questions can call or email. It's useful to have the date noted, and a brief statement of intention. On the other hand, this isn't meant to be busy work; it's meant to make maintenance easier--so don't go overboard. One other good reason to put your name on it: take credit! This is your craft */
然后再往下走一点:
#include "xxxMsg.h" // xxx messages /* MAB 08-05-2004: With respect to the comment above, I gathered that from the filename. I think I need either more or less here. For one thing, xxxMsg.h is automatically generated from the .mc file. That might be interesting information. Another thing is that xxxMsg.h should NOT be added to source control, because it's auto-generated. Alternatively, don't bother with a comment at all. */
然后又一次:
/* MAB 08-05-2004: Defining a keyword?? This seems problemmatic [sic], in principle if not in practice. Is this a common idiom? */
AHHHRRRGGHHH刚刚在一些古老的代码中找到了这个,打赌这家伙认为他很有趣
private //PRIVATE means PRIVATE so no comments for you function LoadIt(IntID: Integer): Integer;
最糟糕的评论是对代码所做的错误解释.这比没有评论更糟糕.
我在代码中看到过这样的东西有太多的注释(不应该存在,因为代码本身就足够清晰),并且它主要发生在代码更新(重构,修改等)时但评论不随其更新.
一个好的经验法则是:只写注释来解释为什么代码在做什么,不是什么它.
绝对必须是代替错误处理的注释.
if(some_condition){ do_stuff(); } else{ //An error occurred! }
我刚刚发现了这个,在注释掉的代码行之前就写在了一行:
//This causes a crash for some reason. I know the real reason but it doesn't fit on this line.
从vb6移植到vb.net的100k LOC应用程序.看起来好像以前的开发人员在一个方法上放置了一个注释标题,然后将确切的注释复制并粘贴到他从那时起编写的每个方法上.数百种方法,每一种都错误评论......
当我第一次看到它时,我笑了...... 6个月后这个笑话很薄.
这是数据库触发器的一个绝对真实的例子:
/****************************************************************************** NAME: (repeat the trigger name) PURPOSE: To perform work as each row is inserted or updated. REVISIONS: Ver Date Author Description --------- ---------- --------------- ------------------------------------ 1.0 27.6.2000 1. Created this trigger. PARAMETERS: INPUT: OUTPUT: RETURNED VALUE: CALLED BY: CALLS: EXAMPLE USE: ASSUMPTIONS: LIMITATIONS: ALGORITHM: NOTES: ******************************************************************************/
/** function header comments required to pass checkstyle */
我见过的两个最无益的评论......
try { ... } catch { // TODO: something catchy }
我也在Daily WTF上发布了这个,所以我将其修改为评论......
// TODO: The following if block should be reduced to one return statememt: // return Regex.IsMatch(strTest, NAME_CHARS); if (!Regex.IsMatch(strTest, NAME_CHARS)) return false; else return true;
一个我从来没有发现非常有用的: