Help us learn about your current experience with the documentation. Take the survey.

代码注释

核心原则

代码应自解释,避免额外注释应成为首要目标。 可以通过使用描述性的方法命名、利用 Ruby 的表达能力、 使用关键字参数、创建小型单一用途的方法、遵循惯用约定、使用枚举等方式来增强这一点。

如果代码本身不够自解释, 注释在提供无法仅通过代码表达的上下文和理由方面可以发挥关键作用。

代码注释与代码本身同等重要。 它们应随着代码的演进或我们对系统理解的加深而得到维护、更新和完善。

需要遵循的关键原则:

  • 注释应尽可能贴近其所引用的代码
  • 注释应详尽但避免冗余
  • 假设下一个阅读此代码的人没有上下文,且理解时间有限

代码注释应更关注"为什么",而不是"做什么"或"怎么做"

代码本身应清晰地表达其功能。 在注释中解释功能会增加额外的维护负担, 因为当代码更改时,注释可能会过时,从而可能导致混淆。 相反,注释应解释为什么做出某些决定或为什么采用特定方法。

例如:

  • 解决系统限制
  • 处理可能不那么明显的边界情况
  • 实现需要深厚领域知识的复杂业务逻辑
  • 处理遗留系统约束

良好注释的示例:

# 注意:我们需要在这里单独处理 nil 值,因为外部支付 API
# 对空字符串和 null 值的处理方式不同。
# 参见:https://api-docs.example.com/edge-cases
def process_payment_amount(amount)
  # 实现
end

不必要的注释示例:

# 计算总金额
def calculate_total(items)
  # 实现
end

更高层次的代码注释和类/模块级文档

GitLab 代码库有许多在多处重用的库。 其中一些库(例如 ExclusiveLeaseHelpers) 具有复杂的内部实现,阅读和理解使用这些库的影响需要花费大量时间。 同样,其中一些库有多个选项,这些选项的重要结果 仅通过阅读参数名称很难理解。

我们没有硬性规定这些库是否应该在面向开发者的独立 Markdown 文件中记录, 还是作为类/模块/方法上方的注释,我们在整个 GitLab 代码库中看到这两种方法的混合使用。 无论哪种情况,我们都认为文档的价值随着库的广泛使用而增加, 随着库实现和接口更改频率的增加而减少。

用于后续操作的注释

每当您在代码中添加预期将来要解决的注释时, 请创建一个技术债务问题。然后在您创建的代码注释中链接到它。 这使其他开发人员可以快速检查注释是否仍然相关, 以及需要做什么来解决它。

示例:

# 在 code_owner 列迁移到 rule_type 之前,此范围已弃用。
# 将在 https://gitlab.com/gitlab-org/gitlab/-/issues/11834 中移除。
scope :code_owner, -> { where(code_owner: true).or(where(rule_type: :code_owner)) }

类和方法文档

如果记录方法参数或返回值,请使用 YARD 语法。

不使用 YARD 语法的示例:

class Order
  # 通过电子邮件地址查找与用户关联的订单 ID。
  def order_ids_by_email(email)
    # ...
  end
end

使用 YARD 语法的示例:

class Order
  # 通过电子邮件地址查找与用户关联的订单 ID。
  #
  # @param email [String, Array<String>] 用户的电子邮件地址
  # @return [Array<Integer>]
  def order_ids_by_email(email)
    # ...
  end
end

如果方法的返回值未被使用,YARD @return 类型应标注为 void, 并且方法应显式返回 nil。这种模式明确了返回值不应被使用, 并防止在链式调用或赋值中意外使用。 例如:

class SomeModel < ApplicationRecord
  # @return [void]
  def validate_some_field
    return unless field_is_invalid

    errors.add(:some_field, format(_("some message")))

    # 对于 void 方法显式返回 nil
    nil
  end
end

有关更多背景和信息,请参阅 合并请求评论