way-go-style

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Way Go Style

Way Go 代码风格

Project Setup (AGENTS.md)

项目配置(AGENTS.md)

Go projects MUST include this skill's Way Specific Conventions in their
AGENTS.md
file to ensure compliance.
  1. Reference this skill: Under "Local Skills".
  2. Copy Conventions: Copy the Way Specific Conventions section below into
    AGENTS.md
    under "Key Conventions".
Go项目必须在其
AGENTS.md
文件中包含本技能的Way 专属规范,以确保合规性。
  1. 引用本技能:在“Local Skills”部分下。
  2. 复制规范:将下方的Way 专属规范部分复制到
    AGENTS.md
    的“Key Conventions”下。

Way Specific Conventions

Way 专属规范

  • Testing: Use standard
    testing
    and
    github.com/google/go-cmp/cmp
    only. No frameworks (Testify, Ginkgo, etc.).
  • Linting: Run
    GolangCI-Lint
    v2. Configure via project-specific
    .golangci.yml
    .
  • Build: Use
    way-magefile
    skill.
  • Encore: Use
    encore-go-*
    skills. Encore conventions (e.g., globals) take precedence.
  • 测试:仅使用标准
    testing
    包和
    github.com/google/go-cmp/cmp
    。禁止使用其他测试框架(如Testify、Ginkgo等)。
  • 代码检查:运行
    GolangCI-Lint
    v2版本。通过项目专属的
    .golangci.yml
    文件进行配置。
  • 构建:使用
    way-magefile
    技能。
  • Encore:使用
    encore-go-*
    系列技能。Encore相关规范(如全局变量)优先级更高。

Overview

概述

This skill provides a condensed reference for writing high-quality Go code, synthesizing advice from "Effective Go", Google's "Code Review Comments", and other authoritative sources. It focuses on idiomatic usage, correctness, and maintainability.
本技能为编写高质量Go代码提供了浓缩参考,整合了《Effective Go》、谷歌《代码评审注释》及其他权威来源的建议。重点关注地道用法、正确性与可维护性。

Effective Go Idioms

《Effective Go》地道用法

Critical idioms from Effective Go.
来自Effective Go的关键地道用法。

Control Flow & Error Handling

控制流与错误处理

  • Defer Evaluation: Arguments to deferred functions are evaluated immediately at the call site (not at execution).
  • Init Scope: Use
    if err := f(); err != nil
    to restrict variable scope.
  • Switch: Use tagless
    switch { case condition: ... }
    instead of long
    if-else
    chains.
  • Internal Panic/Recover: Use
    panic
    to simplify deep error handling in complex internal code (e.g., parsers), but always
    recover
    at the package boundary to return a standard
    error
    .
  • Defer 参数求值:被defer的函数的参数会在调用点立即求值(而非执行时)。
  • 变量作用域初始化:使用
    if err := f(); err != nil
    来限制变量作用域。
  • Switch语句:使用无标签的
    switch { case condition: ... }
    替代冗长的
    if-else
    链。
  • 内部Panic/Recover:在复杂的内部代码(如解析器)中使用
    panic
    简化深层错误处理,但必须在包的边界处使用
    recover
    ,并返回标准
    error
    类型。

Types & Interfaces

类型与接口

  • Functional Adapters: Define methods on function types (e.g.,
    type MyFunc func()
    ) to satisfy interfaces. See
    http.HandlerFunc
    .
  • Interface Verification: Use a global blank assignment to ensure a type satisfies an interface at compile time:
    var _ Interface = (*Type)(nil)
    .
  • 函数适配器:为函数类型(如
    type MyFunc func()
    )定义方法以满足接口要求。可参考
    http.HandlerFunc
  • 接口校验:使用全局空白赋值在编译期确保类型实现了接口:
    var _ Interface = (*Type)(nil)

Google Style Decisions & Best Practices

谷歌风格决策与最佳实践

Key decisions from the Google Go Style Guide and Code Review Comments.
来自Google Go 风格指南代码评审注释的关键决策。

Core Principles

核心原则

  • Clarity: "Clear to the reader" is priority #1. Explain why, not just what.
  • Simplicity: "Least Mechanism". Prefer core constructs (slices, maps) over complex abstractions.
  • Concision: High signal-to-noise ratio. Avoid boilerplate.
  • 清晰性:“对读者清晰易懂”是首要原则。要解释原因,而非仅说明内容
  • 简洁性:“最小机制”。优先使用核心构造(切片、映射)而非复杂抽象。
  • 简洁性:高信噪比。避免冗余模板代码。

Naming & Structure

命名与结构

  • Packages: Single-word, lowercase (e.g.,
    task
    , not
    task_manager
    ). Avoid
    util
    ,
    common
    .
  • Receivers: 1-2 letter abbreviations (e.g.,
    c
    for
    Client
    ). NEVER use
    me
    ,
    this
    ,
    self
    .
  • Constants: Always
    MixedCaps
    (e.g.,
    MaxLength
    ), even if exported. NEVER
    MAX_LENGTH
    .
  • Getters:
    Owner()
    (not
    GetOwner
    ).
  • Interfaces: One-method interfaces ->
    Method
    +
    -er
    (e.g.,
    Reader
    ). Define in the consumer package. Keep them small.
  • :单单词、小写(如
    task
    ,而非
    task_manager
    )。避免使用
    util
    common
    这类名称。
  • 接收者:1-2个字母的缩写(如
    Client
    类型用
    c
    )。绝对禁止使用
    me
    this
    self
  • 常量:始终使用
    MixedCaps
    命名法(如
    MaxLength
    ),即使是导出的常量也不例外。绝对禁止使用
    MAX_LENGTH
    这类全大写下划线分隔的命名。
  • 获取方法:使用
    Owner()
    (而非
    GetOwner
    )。
  • 接口:单方法接口命名为
    方法名+-er
    (如
    Reader
    )。在调用方包中定义接口。保持接口粒度小巧。

Functions & Methods

函数与方法

  • Receiver Type:
    • Pointer (
      *T
      ):
      If mutating, contains
      sync.Mutex
      , or large struct.
    • Value (
      T
      ):
      Maps, channels, functions, small immutable structs.
    • Consistency: Prefer all pointers or all values for a type's methods.
  • Pass Values: Don't pass pointers to small types (
    *string
    ,
    *int
    ) just to save memory.
  • Synchronous: Prefer synchronous APIs. Let the caller decide to use goroutines.
  • Must Functions:
    MustXYZ
    panic on failure. Use only for package-level init or test helpers.
  • 接收者类型
    • 指针类型(
      *T
      :当需要修改接收者、包含
      sync.Mutex
      ,或接收者是大型结构体时使用。
    • 值类型(
      T
      :映射、通道、函数,以及小型不可变结构体使用值类型。
    • 一致性:同一类型的方法应统一使用指针接收者或值接收者。
  • 传递值:不要为了节省内存而传递小型类型的指针(如
    *string
    *int
    )。
  • 同步优先:优先使用同步API。由调用方决定是否启用goroutine。
  • Must系列函数
    MustXYZ
    函数在执行失败时会触发panic。可用于包级初始化或测试辅助函数。

Error Handling

错误处理

  • Flow: Handle errors immediately (
    if err != nil { return err }
    ). Keep "happy path" unindented. Avoid
    else
    .
  • Structure: Use
    %w
    with
    fmt.Errorf
    to wrap errors for programmatic inspection (
    errors.Is
    ).
  • Panics: Never panic in libraries. Return errors.
    log.Fatal
    is okay in
    main
    .
  • Strings: Lowercase, no punctuation (e.g.,
    fmt.Errorf("something bad")
    ) for easy embedding.
  • 流程:立即处理错误(
    if err != nil { return err }
    )。保持“正常路径”代码无缩进。避免使用
    else
  • 结构:使用
    fmt.Errorf
    配合
    %w
    包装错误,以便程序通过
    errors.Is
    进行检查。
  • Panic绝对禁止在库代码中触发panic。应返回错误。在
    main
    函数中使用
    log.Fatal
    是允许的。
  • 错误字符串:使用小写字母,无标点符号(如
    fmt.Errorf("something bad")
    ),便于嵌入其他文本。

Concurrency

并发

  • Lifetimes: Never start a goroutine without knowing how it stops.
  • Context: Always first arg
    ctx context.Context
    . Never store in structs.
  • Copying: Do not copy structs with
    sync.Mutex
    or
    bytes.Buffer
    .
  • 生命周期:绝不要在不清楚如何停止的情况下启动goroutine。
  • Context:始终将
    ctx context.Context
    作为函数的第一个参数。绝对禁止将Context存储在结构体中。
  • 复制禁止复制包含
    sync.Mutex
    bytes.Buffer
    的结构体。

Testing

测试

  • Framework: Use
    testing
    package. No assertion libraries (use
    cmp
    for diffs).
  • Helpers: Mark setup/teardown functions with
    t.Helper()
    .
  • Failure Messages:
    YourFunc(%v) = %v, want %v
    . (Got before Want).
  • Table-Driven: Use field names in struct literals for clarity.
  • Subtests: Use
    t.Run()
    for clear scope and filtering. Avoid slashes in names.
  • 框架:使用
    testing
    包。禁止使用断言库(对比差异时使用
    cmp
    )。
  • 辅助函数:使用
    t.Helper()
    标记测试的初始化/清理函数。
  • 失败信息:格式为
    YourFunc(%v) = %v, want %v
    (实际结果在前,期望结果在后)。
  • 表驱动测试:在结构体字面量中使用字段名以提升可读性。
  • 子测试:使用
    t.Run()
    实现清晰的测试范围与过滤功能。测试名称中避免使用斜杠。

Global State & Init

全局状态与初始化

  • Avoid Globals: Libraries should not rely on package-level vars. Allow clients to instantiate (
    New()
    ).
  • Initialization: Use
    :=
    for non-zero values. Use
    var t []T
    (nil) for empty slices.
  • Imports: Group order: Stdlib, Project/Vendor, Side-effects (
    _
    ). No
    .
    imports.
  • 避免全局变量:库代码不应依赖包级变量。应允许调用方自行实例化(通过
    New()
    函数)。
  • 初始化:非零值使用
    :=
    进行初始化。空切片使用
    var t []T
    (初始为nil)。
  • 导入:分组顺序:标准库、项目/第三方依赖、副作用导入(
    _
    )。禁止使用
    .
    导入。

Practical Go Cheat Sheet

实用Go 速查表

Best practices for maintainable Go from Dave Cheney's Practical Go.
来自Dave Cheney的Practical Go的可维护Go代码最佳实践。

Guiding Principles

指导原则

  • Simplicity, Readability, Productivity: The core values. Clarity > Brevity.
  • Identifiers: Choose for clarity. Length proportional to scope/lifespan. Don't include type in name (e.g.,
    usersMap
    ->
    users
    ).
  • 简洁性、可读性、生产力:这是核心价值。清晰性优先于简洁性。
  • 标识符:选择清晰的命名。名称长度应与作用域/生命周期成正比。不要在名称中包含类型信息(如
    usersMap
    应改为
    users
    )。

Design & Structure

设计与结构

  • Package Names: Name for what it provides (e.g.,
    http
    ), not what it contains. Avoid
    util
    ,
    common
    .
  • Project Structure: Prefer fewer, larger packages. Arrange files by import dependency.
  • API Design: Hard to misuse. Avoid multiple params of same type. Avoid
    nil
    params.
  • Interfaces: Let functions define behavior they require (e.g., take
    io.Writer
    not
    *os.File
    ).
  • Zero Value: Make structs useful without explicit initialization (e.g.,
    sync.Mutex
    ,
    bytes.Buffer
    ).
  • 包名:根据包所提供的功能命名(如
    http
    ),而非包内包含的内容。避免使用
    util
    common
  • 项目结构:优先使用数量少、规模大的包。根据导入依赖关系组织文件。
  • API设计:设计难以被误用的API。避免多个相同类型的参数。避免使用
    nil
    参数。
  • 接口:让函数定义其所需的行为(如接收
    io.Writer
    而非
    *os.File
    )。
  • 零值可用性:让结构体无需显式初始化即可使用(如
    sync.Mutex
    bytes.Buffer
    )。

Concurrency & Errors

并发与错误

  • Concurrency: Leave it to the caller. Never start a goroutine without knowing when/how it stops.
  • Errors: Eliminate error handling by eliminating errors (e.g.,
    bufio.Scanner
    ). Handle errors once (don't log AND return).
  • Return Early: Use guard clauses. Keep the "happy path" left-aligned.
  • 并发:将并发决策交给调用方。绝不要在不清楚何时/如何停止的情况下启动goroutine。
  • 错误:通过消除错误场景来减少错误处理(如
    bufio.Scanner
    )。错误只处理一次(不要既记录日志又返回错误)。
  • 提前返回:使用卫语句。保持“正常路径”代码左对齐。

Available References

可用参考资料

Detailed documentation available in the
references/
directory:
  • Effective Go: (HTML) The foundational guide to idiomatic Go.
  • Code Review Comments: Common comments made during Go code reviews at Google.
  • Google Style Guide: Complete set of Google's Go style documents.
    • Guide: Core guidelines.
    • Decisions: Normative style decisions.
    • Best Practices: Evolving guidance.
  • Practical Go: Dave Cheney's advice on writing maintainable Go programs.
详细文档位于
references/
目录下:
  • Effective Go:(HTML格式)地道Go代码的基础指南。
  • Code Review Comments:谷歌内部Go代码评审中的常见注释。
  • Google Style Guide:谷歌完整的Go风格文档集合。
    • Guide:核心指南。
    • Decisions:规范性风格决策。
    • Best Practices:演进中的最佳实践。
  • Practical Go:Dave Cheney关于编写可维护Go程序的建议。",