写给三个月后的自己的注释
目录
- 「这里需要重构」——最温柔的谎言
- 注释越详细,记忆越模糊
- TODO 的语义学
- 一个三个月前的自己留下的坑
- 尾声:注释不是写给计算机的
「这里需要重构」——最温柔的谎言
凌晨三点,我在改一个正则表达式。
# FIXME: this regex is a disaster, refactor ASAP
这是我三个月前自己写的注释。我不记得当时遇到了什么问题,也不记得为什么觉得「ASAP」是一个合理的时间承诺。我只知道现在凌晨三点,我被三个月前的自己坑了。
我盯着那行注释看了十秒,把 ASAP 改成了 LOL,然后继续改正则。
这不是我第一次被自己的注释骗了。事实上,每次回头看自己代码,注释都在对我说同一个故事:过去那个我,对未来那个我的工作效率,有着完全不切实际的乐观。
注释越详细,记忆越模糊
有一种注释特别危险:那种特别详细、特别耐心的,一行一行解释「这里在干什么」的。
# 从 response JSON 中提取 user_id 字段
# 如果字段不存在或为空,返回默认值 'anonymous'
# 默认值定义在 config.DEFAULT_USER_ID 中(见 config.py 第 47 行)
# 注意:这个字段在 v2 API 中改名为 'userIdentity'
# 但我们还在呼吁前端团队升级,所以暂时兼容两种命名
我第一次看到这种注释时觉得写注释的人太贴心了。第二次看到,觉得这个人是不是不太信任自己。第三次看到——也是我第一次真正遇到 bug 的时候——我发现注释越长,代码本身越难读。
不是注释不好。是这个人在写注释的时候,他的大脑已经在处理「如何解释」而不是「如何正确」了。注释用文字质量补偿了代码的设计问题。这个模式很常见:你在写一个复杂函数时觉得「我得在这里写个注释」,但实际上你真正该做的是把这个函数拆成三个小函数,让代码自己解释自己。
TODO 的语义学
我花了一整年在理解不同 TODO 前缀的真正语义:
| 写法 | 真实含义 |
|---|---|
TODO |
我不会做的 |
FIXME |
我知道这里有问题,但我不打算现在修 |
HACK |
我知道这个方案很离谱,但它能过 CI |
XXX |
有人在这里遇到了很大的麻烦,但他没时间解释 |
OPTIMIZE |
性能瓶颈?那是下个版本的事 |
ASAP |
三个月后我会凌晨三点坐在这里改正则 |
最诚实的注释是我见过的一次:
# I have no idea why this works. Don't touch it.
零伪装,零承诺,纯粹的生存智慧。写这行注释的人一定被自己坑过很多次。
一个三个月前的自己留下的坑
说回到那个正则表达式。我改完之后,顺手 git log 了一下看当时是谁写的这行代码。
是我。三个月前的我。
commit message 写的是 fix: edge case in URL parsing。改了两个文件,涉及 23 行代码。我完全不记得这件事了。
但那个 commit 里还有一个小细节:我当时加了一个 # NOTE: 这个 URL pattern 在 staging 上测过,production 可能不一样。
production 确实不一样。我今天凌晨三点坐在这里就是因为这个。
我忍不住笑了一下——不是那种愉快的笑,是那种「三个月前的自己已经知道会有今天了」的无奈。他知道会有问题,他用了注释来警告未来的我,但他没有现场修掉。因为他太困了,或者因为 deadline 压着,或者因为「ASAP」在三个月前看起来真的很快。
尾声:注释不是写给计算机的
注释是写给人类的。而且是写给特定的人类——三个月后的自己。
编译器会忽略注释,linter 会忽略注释,代码审查者可能扫一眼就过。只有未来某个凌晨三点的你会真正读它们。
所以我现在写注释的风格变了:
- 不再写
# 这里在做什么——那应该是代码自己告诉你的 - 不再写
# FIXME ASAP——那是对未来自己的道德绑架 - 会写
# 三个月前的我觉得这个方案可行。现在我要告诉你:别信他。 - 会写
# 下面这个函数不是最优解,但它能在两个小时内通过所有测试。有时候这样就够了。
承认吧。你写注释的时候,其实是在给未来的自己写信。
而那些信,你总有一天会读到。
评论(0)
暂无评论,来写第一条吧~