go-google-style-decisions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

go-google-style-decisions

Go语言Google风格指南之决策细则

This skill provides expert guidance on the "Decisions" portion of the Google Go Style Guide. It focuses on the specific choices and trade-offs made to ensure consistency, readability, and maintainability across large Go codebases.
本技能为Google Go风格指南中的“决策”部分提供专业指导,重点关注为确保大型Go代码库的一致性、可读性和可维护性而做出的具体选择与权衡。

Core Mandates

核心准则

  1. Clarity over Conciseness: While Go favors brevity, never sacrifice clarity.
  2. Consistency is Key: Adhere to established patterns in the codebase.
  3. Idiomaticity: Follow Go-specific patterns (e.g., error handling, interface usage).
  4. No Underscores: Avoid underscores in names except in specifically allowed cases (tests, generated code).
  1. 清晰优先于简洁:尽管Go语言推崇简洁,但绝不能以牺牲清晰性为代价。
  2. 一致性是关键:遵循代码库中已确立的模式。
  3. 符合语言习惯:遵循Go语言特有的模式(如错误处理、接口使用)。
  4. 禁用下划线:除特殊允许的情况(测试代码、生成代码)外,名称中避免使用下划线。

Developer Workflow

开发者工作流程

  1. Design: Plan APIs following the "Least Mechanism" principle.
  2. Implement: Write code adhering to the style decisions detailed below.
  3. Lint: Use
    golangci-lint
    or
    go vet
    to catch common style violations.
  4. Test: Include runnable examples in
    _test.go
    files for public APIs.
  5. Review: Ensure changes align with the "Core Principles" of clarity and consistency.
  1. 设计:遵循“最小机制”原则规划API。
  2. 实现:按照下文详述的风格决策编写代码。
  3. 代码检查:使用
    golangci-lint
    go vet
    检查常见的风格违规问题。
  4. 测试:在
    _test.go
    文件中为公开API添加可运行的示例。
  5. 评审:确保变更符合“清晰性与一致性”的核心准则。

Detailed Guidance

详细指导

For the complete guide, consult references/decisions.md.
如需完整指南,请查阅references/decisions.md

1. Naming Conventions

1. 命名约定

  • Underscores: Do not use underscores in Go names (e.g.,
    pkg_name
    or
    var_name
    ).
    • Exceptions:
      _test.go
      files, generated code, and low-level interop.
  • Package Names:
    • Short, lowercase, single word. No
      util
      or
      common
      .
    • Avoid common variable names (e.g.,
      user
      as a package name if
      user
      is a common variable).
  • Receiver Names:
    • Short (1-2 letters).
    • Consistently used throughout the type's methods.
    • Usually an abbreviation of the type (e.g.,
      c
      for
      Client
      ).
  • Constant Names:
    • Use
      MixedCaps
      (e.g.,
      ExportedConst
      ,
      internalConst
      ).
    • Do NOT use
      ALL_CAPS
      or
      kPrefix
      .
  • Initialisms:
    • Maintain consistent casing (e.g.,
      HTTPClient
      ,
      urlPath
      ,
      XMLParser
      ).
  • Getters:
    • Omit
      Get
      prefix (e.g., use
      obj.Field()
      instead of
      obj.GetField()
      ).
    • Use
      Get
      only if the method is truly "getting" something that isn't a simple field (e.g.,
      GetURL
      ).
  • Variable Names:
    • Length should be proportional to scope. Short names for small scopes (e.g.,
      i
      in a loop), more descriptive names for larger scopes.
    • Omit types from names (e.g.,
      users
      instead of
      userSlice
      ).
  • 下划线:Go语言名称中不得使用下划线(如
    pkg_name
    var_name
    )。
    • 例外情况
      _test.go
      文件、生成代码以及底层互操作代码。
  • 包名称
    • 简短、小写、单个单词。禁止使用
      util
      common
    • 避免使用常见变量名作为包名(例如,如果
      user
      是常用变量,则不要将
      user
      作为包名)。
  • 接收者名称
    • 简短(1-2个字母)。
    • 在该类型的所有方法中保持一致。
    • 通常是类型的缩写(例如,
      Client
      的接收者用
      c
      )。
  • 常量名称
    • 使用
      MixedCaps
      命名法(如
      ExportedConst
      internalConst
      )。
    • 禁止使用
      全大写
      k前缀
      命名方式。
  • 首字母缩写词
    • 保持大小写一致(如
      HTTPClient
      urlPath
      XMLParser
      )。
  • 获取方法(Getters)
    • 省略
      Get
      前缀(例如,使用
      obj.Field()
      而非
      obj.GetField()
      )。
    • 仅当方法确实是获取非简单字段的内容时才使用
      Get
      前缀(如
      GetURL
      )。
  • 变量名称
    • 长度应与作用域大小成正比。小作用域使用短名称(如循环中的
      i
      ),大作用域使用更具描述性的名称。
    • 名称中省略类型信息(例如,使用
      users
      而非
      userSlice
      )。

2. Commentary

2. 注释

  • Line Length: Aim for ~80 characters. Wrap long comments.
  • Doc Comments: Every top-level exported name MUST have a doc comment.
    • Must start with the name of the object.
    • Must be a complete sentence.
  • Examples: Provide
    ExampleXxx
    functions in test files to document public APIs.
  • 行长度:目标约80个字符,过长的注释需要换行。
  • 文档注释:所有顶层导出名称必须包含文档注释。
    • 必须以对象名称开头。
    • 必须是完整的句子。
  • 示例:在测试文件中提供
    ExampleXxx
    函数来记录公开API的用法。

3. Error Handling

3. 错误处理

  • Error as Last Return: Always return
    error
    as the final value.
  • Returning Nil: Return
    nil
    for the error value on success.
  • Error Interfaces: Exported functions should return the
    error
    interface, not a concrete type.
  • Error Strings:
    • No capitalization (unless proper nouns/acronyms).
    • No trailing punctuation.
  • Indentation: Handle errors early and return/continue. Keep the "happy path" at the minimal level of indentation.
  • No In-band Errors: Do not use special values (like
    -1
    ) to signal errors. Use
    (value, error)
    or
    (value, ok)
    .
  • 错误作为最后返回值:始终将
    error
    作为最后一个返回值。
  • 返回Nil:成功时返回
    nil
    作为错误值。
  • 错误接口:导出函数应返回
    error
    接口,而非具体类型。
  • 错误字符串
    • 首字母无需大写(专有名词或缩写词除外)。
    • 末尾无需添加标点符号。
  • 缩进:尽早处理错误并返回/继续执行,让“正常路径”保持最小缩进层级。
  • 禁止带内错误:不要使用特殊值(如
    -1
    )来表示错误,应使用
    (value, error)
    (value, ok)
    模式。

4. Language Constructs

4. 语言结构

  • Composite Literals: Use them for struct initialization. Always specify field names when the struct is from another package.
  • Nil Slices: Prefer
    var s []int
    (nil slice) over
    s := []int{}
    (empty slice).
    • Avoid APIs that distinguish between nil and empty slices.
  • Braces:
    • Closing braces should align with the opening statement.
    • Avoid "cuddling" (e.g.,
      if err != nil { ... } else { ... }
      is fine, but don't over-compact).
  • Function Formatting: Keep signatures on one line if possible. If they must wrap, indent the arguments.
  • 复合字面量:使用复合字面量初始化结构体。当结构体来自其他包时,必须指定字段名称。
  • Nil切片:优先使用
    var s []int
    (nil切片)而非
    s := []int{}
    (空切片)。
    • 避免使用区分nil切片和空切片的API。
  • 大括号
    • 闭合大括号应与对应的起始语句对齐。
    • 避免过度紧凑的“拥抱式”写法(例如
      if err != nil { ... } else { ... }
      是可以的,但不要过度压缩)。
  • 函数格式:尽可能将函数签名放在一行。如果必须换行,应对参数进行缩进。

5. Panic and Recovery

5. Panic与Recovery

  • Avoid Panic: Do not use
    panic
    for normal error handling.
  • Exceptional Only: Use
    panic
    only for truly unrecoverable states (e.g., internal invariant failure).
  • Program Termination: Use
    log.Exit
    or
    log.Fatal
    (which calls
    os.Exit
    ) only in
    main
    or
    init
    functions.
  • MustXYZ: Helper functions that terminate the program on failure should be prefixed with
    Must
    (e.g.,
    template.Must
    ).
  • 避免使用Panic:不要在常规错误处理中使用
    panic
  • 仅用于异常情况:仅在真正无法恢复的状态下使用
    panic
    (例如内部不变量失效)。
  • 程序终止:仅在
    main
    init
    函数中使用
    log.Exit
    log.Fatal
    (后者会调用
    os.Exit
    )。
  • Must前缀函数:失败时会终止程序的辅助函数应以
    Must
    为前缀(例如
    template.Must
    )。

6. Copying

6. 复制操作

  • Structs with Locks: Be extremely careful copying structs that contain
    sync.Mutex
    or other synchronization primitives.
  • Pointer Receivers: If a type has methods with pointer receivers, avoid copying values of that type.
  • 含锁结构体:复制包含
    sync.Mutex
    或其他同步原语的结构体时需格外小心。
  • 指针接收者:如果某个类型拥有指针接收者的方法,应避免复制该类型的值。

References

参考资料