为代码编写更有意义的注释
TL;DR:
- 解释为什么这里有这段代码而不是这段代码在做什么;
- 不要编写会让人困惑的注释;
- 尽可能让其它未接触这段代码的人或未来的自己能看懂这段代码为什么这么做;
Good code is self-documented.
下面将逐个举例糟糕和良好的代码注释。
1.解释为什么这里有这段代码而不是这段代码在做什么
下面的是糟糕的注释,因为它只描述了代码在干什么,而任何软件工程师都能很容易的知道代码在做什么, 所以导致这段注释失去了存在的意义:
val text = "Hello, World!"
// Remove characters not in the alphabet.
val sanitizedText = text.replaceRegex("""\W+""", "")
someFunction(sanitizedText)
下面的是良好的注释,它解释了为什么要替换掉 text
内的部分字符:
val text = "Hello, World!"
// `someFunction()` accepts characters from the english alphabet only, so
// characters not in the alphabet have to be removed.
val sanitizedText = text.replaceRegex("""\W+""", "")
someFunction(sanitizedText)
2. 不要编写会让人困惑的注释
下面的是糟糕的注释,这段注释看起来是想提醒编译器要更新 previousState
的值,但对阅读代码的
人来说这段注释可能会被他/她曲解为 “注释要我记得更新 previousState
,那我该怎么更新它?它是
已经在下面更新了吗?那我还要不要更新它?”:
var previousState = ConnectivityState.Disconnected
while (previousState != ConnectivityState.Connected) {
if (previousState = ConnectivityState.Connecting) {
// Some lenghtly code here
// that may span over pages.
}
// Remember to update the variable.
previousState = ConnectivityState.next()
}
下面的是良好的注释,它解释了那段代码存在的意义:
var previousState = ConnectivityState.Disconnected
while (previousState != ConnectivityState.Connected) {
if (previousState = ConnectivityState.Connecting) {
// Some lenghtly code here
// that may span over pages.
}
// Update this variable so the next time this loop executes it will be the
// state in the previous loop.
previousState = ConnectivityState.next()
}
3. 尽可能让其它未接触这段代码的人或未来的自己能看懂这段代码为什么这么做
我经常会遇到我无法理解内个月甚至几个星期前我自己写的代码,又可能是别人接手我的代码的时候不断的问 我这段代码是什么意思,那段代码是什么意思,因此在写注释时要帮助别人或未来的自己更好的理解为什么 这里有这样一段代码。
一个我目前在实践的办法就是 “假定阅读这段代码的人没有关于这段代码的任何先前认知 (Prior Knowledge)",尽可能的想读者解释这段代码在做什么,更重要的是告诉读者为什么这段代码存在 于此。
4. Good code is self-documented
Let’s face it.
就算是函数或变量名很清晰的表达了它是什么,整段代码读起来通俗易懂,但和其它代码或函数组合后其含义
就完全不一样了,又或者是其它现在看起来还很合理但未来就变成了毫无逻辑的代码。
因此,减少对自己的代码的过度自信。如果写的代码看起来不容易理解它的含义和或存在的意,那就写注释
来解释它存在的意义。