mcpField
W
writing-code-comments

writing-code-comments

github.com/posthog开发40.5k112 次安装今天更新
代码仓库

关于 writing-code-comments

面向开发者的代码注释编写技能,默认不添加注释,并说明如何只保留代码无法表达的背景,例如原因、警告或外部引用。

主要功能

  1. 01判断注释是否补充背景
  2. 02删除代码复述与过时历史
  3. 03保留原因说明与警告
  4. 04提供注释风格指引

适用场景

  1. 01审查代码变更中的注释
  2. 02判断是否需要添加注释
  3. 03修改注释以提高清晰度

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/posthog/posthog --skill writing-code-comments

安装后在 Claude Code 中输入/writing-code-comments确认已加载。

详细介绍

编写代码注释

在添加或编辑任何注释之前先运行此流程。默认不写注释。命名清晰的优秀代码本身就能承载大部分含义;只有当注释能告诉读者代码本身无法表达的内容时,它才值得存在。

关口:一个问题

在编写注释之前,先回答:

这条注释告诉了未来的读者什么代码本身没有表达的信息?

如果答案是“它只是在复述代码做了什么”,删掉它。改为重命名变量或提取函数。

值得保留的注释回答的是代码无法表达的 为什么:

  • ✅ # ATOMIC_REQUESTS is off, so wrap the two writes that must commit together
  • ✅ // Stripe sends the amount in cents; the rest of our system uses dollars
  • ✅ # Kept in sync with the enum in migrations/0042; update both

删除这些

复述代码的叙述
  • ❌ counter += 1 上方的 # increment the counter
  • ❌ for user of users 上方的 // loop over users
  • ❌ return result 上方的 # return the result

如果一段代码需要靠叙述才能被理解,解决办法是拆成更小的函数和更好的命名,而不是加注释。

变更历史和聊天上下文

永远不要记录代码是如何演变成现在这样的。那属于提交信息和 PR 描述,在那里它与 diff 关联且可被搜索。放在源码里只是噪音,而且会立刻过时。

  • ❌ # previously used a set here, switched to a list for ordering
  • ❌ // per PR #1234 / # as discussed / # changed because the old way broke
  • ❌ # AI: generated this helper / // agent: refactored
  • ❌ 在迁移早已完成之后仍留在代码里的 # TODO(2024-01): remove after migration
易过期的测量值和当前状态标记

测量出的耗时、计数和速率会悄无声息地腐烂:没有任何机制强制它们更新,而一个腐烂的数字会误导下一个估算超时或分片数量的人。“currently” / “today” 这类限定词也是如此,因为去掉它们句子陈述的是同一个事实。要陈述这个数字所代表的持久关系。

  • ❌ # skip the ~20 min build,而持久的事实是构建很昂贵
  • ❌ # ci-backend runs ~28m, so 60m ≈ one red result,而不写“按最慢工作流的完整运行时长来设置”
  • ❌ # no story currently opts into webkit snapshots,去掉 “currently” 后陈述的是同一个事实
  • ❌ # ~20 minutes in June, past 25 by July,因为趋势叙述属于变更历史

可以保留的数字:

  • 带日期的快照:# as of August 2024, Homebrew ships 4.13.2(日期让过时变得可见)
  • 对相邻代码字面量的复述:300 旁边的 # runs that took >5 min (300 seconds)(它会随代码一起更新)
  • 平台常量:# GitHub's comment size limit (~64KB)
  • 目标或预算:# Target: ~15 min per shard(这是策略,不是测量值)
  • 有出处的证据:# 30% peak memory observed on 16-core runs (#46853)(链接标明了日期)
注释掉的代码

删掉它;如果以后需要,版本历史里有。注释掉的代码对下一个读者来说是模棱两可的,他无法判断这是一条笔记、一个回滚方案,还是一个意外。

冗余的文档字符串和类型复述
  • ❌ 用散文重复函数名的文档字符串:get_user_by_id 上的 """Gets the user by id."""
  • ❌ 在已有类型的字段上写 # type: string
  • ❌ Python 测试文档注释(本仓库的约定是不写;测试名称本身就说明了问题)

保留这些

  • 代码中不明显的 为什么:一个变通方案、一个性能权衡、一个规范上的怪癖、一个顺序约束。
  • 关于存在于别处之后果的 警告:“修改这里会破坏缓存键”、“调用方依赖它是已排序的”。
  • 指向读者无法从仓库中重建的上下文的 指引:指向规范、工单的链接,或某个令人意外的取值被选定的原因。

风格

像写技术文档那样写注释:明确且精确。说明推理过程,让读者不必自行推断。长度本身不是目标,无论长短:不要为了显得简洁而删减注释,也不要为了显得详尽而堆砌内容。把需要说的说清楚,然后停下。

  • 明确且技术化。 说明原因与结果。指明实际的条件、取值和后果。读者不应需要从一句提示中重构你的推理。
  • 大体使用 ASD-STE100 简化技术英语。 使用主动语态、简单时态、每句一个意思,并保持术语一致。
  • 让长度随内容而定。 一行能覆盖就用一行;推理需要更多空间就用更多。简洁和冗长都不是目标。
  • 不要用破折号。 要避免的迹象是用破折号连接的两段式短语,例如 # do the thing — it's faster。改用真正的连接词("because"、"so that"、"which means"、"to avoid")。
  • 解释为什么,而不是是什么。 是什么在代码里;为什么通常不在。
  • 在移动或重构代码时保留现有注释,除非改动使它们不再正确。不要仅仅因为你在迁移函数,就把已有的“为什么”丢掉。
  • 与周围的密度保持一致。 不要给一个本来没有注释的文件逐行添加注释;也不要把一个注释完善的模块删得干干净净。

破折号的解决办法是连接词,而不是更多的字。破折号去掉后,简短的注释就没问题:

  • ❌ # batch here — avoids N+1
  • ✅ # batch here to avoid an N+1 against posthog_organizationmembership

当你想要写注释时

按顺序尝试:(1) 一个更好的命名,(2) 一个更小的函数,(3) 一个类型。只有当这些都承载不了含义时,才去写注释。

评论

支持 Markdown