代码注释:程序员最大的自我感动

2026-03-12 8 0

代码注释:程序员最大的自 我感动

"好的代码是自解释的,注释是失败的证明。"
—— 这句话害了多少人?

当注释成为代码的遮羞布

每次看到代码库里这种注释,我都替作者尴尬:

// increment i by 1
i++

这是注释?还是在侮辱读者的智商?

我敢说,每个程序员都写过这种注释。但问题是,为什么我们还在假装这是一种"好习惯"?

注释的三大谎言

谎言一:注释越多代码越可读

去GitHub上翻各种"star过万"的知名项目,你会看到一个有趣的现象:

  • 烂项目的注释:比代码还多
  • 好项目的注释:少得可怜

为什么?因为真正好的代码,命名就是注释。

# 烂:
def calc(d):
    # calculate discount
    return d * 0.9

# 好:
def calculate_discount(amount: float) -> float:
    return amount * DISCOUNT_RATE

看到了吗?第二个版本根本不需要注释。函数名、变量名、类型提示,已经把一切都说清楚了。

谎言二:注释不会过时

哈。

你见过最离谱的注释是什么?我见过这种:

// TODO: Remove this hack after fixing issue #1234
// 这个问题已经被标记为 won't fix
// 所以这个hack永远不会被移除了 lol

注释是代码的墓碑。你永远不知道代码改了N轮之后,哪个注释还在原地假装有用。

谎言三:写注释是基本素养

很多团队把"代码必须有注释"写进规范。

然后呢?

/**
 * Gets the name.
 * @return the name
 */
public String getName() {
    return name;
}

这种注释,写了等于没写,还浪费了维护的人。

什么才是注释的正确打开方式

1. 解释"为什么",而不是"是什么"

// 烂注释:
// iterate through the list
for (let item of items) { ... }

// 好注释:
// 使用for...of而不是map,因为这里不需要返回值
// 而且for...of在大量数据时性能更好
for (let item of items) { ... }

注释应该解释代码背后的意图上下文,而不是把代码翻译成人话。

2. 解释那些"不正常"的选择

// 不用strings.ToLower而是手动比较
// 因为ToLower会分配新内存,这在热路径上是不可接受的
// 参考: https://github.com/xxx/performance-issue

这种注释才有价值。读者能理解:哦,原来是有特殊原因的,不是因为作者傻。

3. 复杂的业务逻辑,需要注释

# 这里的计算逻辑:
# 1. 首先过滤掉状态为deleted的记录(业务规定)
# 2. 然后按照创建时间排序,取最新的前100条
# 3. 如果用户设置了只看VIP,则在此基础上再过滤
# 4. 最后还要按照某个复杂的权重算法重新排序
#
# 为什么这么复杂?历史遗留,详见:http://wiki/legacy-reason-123

这种注释就是救命用的。没有它,后来者(包括三个月后的你自己)根本看不懂这段代码在干嘛。

4. 标记未完成和已知问题

# BUG(2024-03): 当amount超过1亿时会溢出
# TODO: 等后端支持高精度Decimal后再修复
# HACK: 临时绕过高并发时的race condition

这种注释有价值,但一定要带足够的上下文!否则就是给自己和后人埋坑。

自文档化代码:一场美丽的骗局

有人会说:"别写注释,让代码自文档化!"

这句话害人不浅。

确实,好的命名、合理的结构、适当的抽象,能让代码更容易理解。但这不代表注释就是多余的。

现实是:

  • 总有一些复杂的业务逻辑,代码本身说不清楚
  • 总有一些"不得不"的hack,需要解释背景
  • 总有一些历史遗留的坑,需要说明来由

"代码自文档化"是理想状态,但不是现实。

我的注释规范

经过多年毒打,我总结出的一套注释原则:

1. 能用代码表达的就别用注释
- 函数名 calculateTotalPriceWithTaxAndDiscount() 比任何注释都强
- 变量名 expiredAt// expiration date 强100倍

2. 注释必须回答"为什么"
- 如果只是说明代码在做什么,删掉
- 如果解释了背后的业务原因、performance 考量、历史遗留,保留

3. 过期注释是技术债务
- 每次code review,发现注释和代码不一致,直接删或改
- 不要留着"万一有用"

4. 注释的敌人是复制粘贴
- 多少注释灾难源于"ctrl+c / ctrl+v"
- 宁可少写注释,也不要复制旧注释

5. 复杂算法的核心思路要写
- 那种你看三天都看不懂的算法,配上核心思路注释
- 但别写成逐行翻译,要写成"设计思路"

最后的真心话

我见过太多程序员,代码写得稀烂,注释写得贼多。

这就像一个人衣服穿得邋里邋遢,却花半小时写了个牌子解释自己为什么这样穿——完全没有抓住重点。

好的代码不需要注释,烂代码配什么注释都没救。

与其纠结"这段代码该不该加注释",不如先问问自己:

  • 命名够不够清晰?
  • 函数职责够不够单一?
  • 逻辑能不能简化?

如果这些都做好了,注释自然是多余的。

如果没做好,堆再多注释也只是在给自己擦屁股,还是那种越擦越脏的擦法。


代码是写给人看的,注释同理。先把代码写好,再考虑注释的事。

相关文章

别再把RESTful奉为圣经了:一位CURD工程师的觉醒
接错一次钱两次怎么办?——接口幂等性的实战指南
还在手动部署AI工具?:是时候当个甩手掌柜了
为什么你的 API 总是被吐槽?——API 设计的七大罪
Go语言错误处理:别再傻傻地if err != nil了
还在自己折腾部署?让小龙虾帮你搞定!OpenClaw代部署服务来了

发布评论