Follow

Follow

# 技術翻譯 - 編寫程式註解的最佳實踐

## Best practices for writing code comments from StackOver flow

·May 31, 2022·

1. 編寫然後維護註解是一項花費
2. 您的編譯器不會檢查您的註解，因此無法確定註解是否正確。
3. 另一方面，您可以保證電腦正在按照您的程式碼告訴它執行的操作。

• Rule 1: Comments should not duplicate the code.
註解不應該重複程式碼
• Rule 2: Good comments do not excuse unclear code.
好的註解不應該成為不清晰程式碼的藉口
• Rule 3: If you can’t write a clear comment, there may be a problem with the code.
如果不能寫清楚的註解，可能是程式碼有問題
• Rule 4: Comments should dispel confusion, not cause it. 註解應該消除混亂，而不是引起混亂
• Rule 5: Explain unidiomatic code in comments.
在註解中解釋單一的程式碼
• Rule 6: Provide links to the original source of copied code.
提供複製程式碼的來源的連結
• Rule 7: Include links to external references where they will be most helpful.
包括外部參考的連結會是相當有幫助的
修復錯誤時添加註解
• Rule 9: Use comments to mark incomplete implementations.
使用註解來標記不完整的實作。

## Rule 1: Comments should not duplicate the code

``````if (x > 3) {
…
} // if
``````

• 增加視覺混亂
• 花時間寫作和閱讀
• 可能會過時

``````i = i + 1;         // Add one to i
``````

``````// create a for loop // <-- comment
for // start for loop
(   // round bracket
// newline
int // type for declaration
i    // name for declaration
=   // assignment operator for declaration
0   // start value for i
``````

## Rule 2: Good comments do not excuse unclear code

``````private static Node getBestChildNode(Node node) {
Node n; // best child node candidate
for (Node node: node.getChildren()) {
// update n if the current state is better
if (n == null || utility(node) > utility(n)) {
n = node;
}
}
return n;
}
``````

``````private static Node getBestChildNode(Node node) {
Node bestNode;
for (Node currentNode: node.getChildren()) {
if (bestNode == null || utility(currentNode) > utility(bestNode)) {
bestNode = currentNode;
}
}
return bestNode;
}
``````

## Rule 3: If you can’t write a clear comment, there may be a problem with the code

Unix 原始碼中最惡名昭著的註解是 "You are not expected to understand this"，它出現在一些雜亂的 context-switching 程式碼之前。Dennis Ritchie 後來解釋說，它的目的是 "in the spirit of ‘This won’t be on the exam,’ rather than as an impudent challenge." 不幸的是，事實證明他和協作者 Ken Thompson 自己也並不理解它，後來不得不重寫它。

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

## Rule 4: Comments should dispel confusion, not cause it

[Peter Samson] was particularly obscure in refusing to add comments to his source code explaining what he was doing at a given time. One well-distributed program Samson wrote went on for hundreds of assembly-language instructions, with only one comment beside an instruction that contained the number 1750. The comment was RIPJSB, and people racked their brains about its meaning until someone figured out that 1750 was the year Bach died, and that Samson had written an abbreviation for Rest In Peace Johann Sebastian Bach.
[Peter Samson] 拒絕在他的原始碼中增加註解來解釋，他在給定時間所做的事情特別晦澀難懂。Samson 編寫的一個分佈良好的程式繼續執行數百條組合語言指令，在包含行數 1750 的指令旁邊只有一條註解。註解是 RIPJSB，人們絞盡腦汁想知道它的含義，直到有人發現 1750 是巴赫去世的那一年，Samson 寫了《安息吧約翰·塞巴斯蒂安·巴赫》的縮寫。

## Rule 5: Explain unidiomatic code in comments

``````final Object value = (new JSONTokener(jsonString)).nextValue();
// Note that JSONTokener.nextValue() may return
// a value equals() to null.
if (value == null || value.equals(null)) {
return null;
}
``````

``````if (b == true)
``````

``````if (b)
``````

``````if (b != null && b)
``````

• 解決了什麼問題
• 誰提供了代碼
• 為什麼推薦該解決方案
• 評論者怎麼想的
• 是否仍然有效
• 如何改進

``````/** Converts a Drawable to Bitmap. via https://stackoverflow.com/a/46018816/2219998. */
``````

• 程式碼的作者是 Tomáš Procházka，他在 Stack Overflow 上排名前 3%。
• 一位評論者提供了一種優化，已合併到 Repo。
• 另一位評論者提出了一種避免極端情況的方法。

``````// Magical formula taken from a stackoverflow post, reputedly related to
// human vision perception.
return (int) (0.3 * red + 0.59 * green + 0.11 * blue);
``````

``````// Many thanks to Chris Veness at http://www.movable-type.co.uk/scripts/latlong.html
// for a great reference and examples.
``````

``````// http://tools.ietf.org/html/rfc4180 suggests that CSV lines
// should be terminated by CRLF, hence the \r\n.
csvStringBuilder.append("\r\n");
``````

``````// NOTE: At least in Firefox 2, if the user drags outside of the browser window,
// mouse-move (and even mouse-down) events will not be received until
// the user drags back inside the window. A workaround for this issue
// exists in the implementation for onMouseLeave().
@Override
public void onMouseMove(Widget sender, int x, int y) { .. }
``````

``````// Use the name as the title if the properties did not include one (issue #1425)
``````

## Rule 9: Use comments to mark incomplete implementations

``````// TODO(hal): We are making the decimal separator be a period,
// regardless of the locale of the phone. We need to think about
// how to allow comma as decimal separator, which will require
// updating number parsing and other places that transform numbers
// to strings, such as FormatAsDecimal
``````