关于 golang-style
golang-style 是一组 Go 编码规范,供编写 Go 代码时遵循。内容涵盖错误处理、命名、注释、代码结构和文档查询等约定。
主要功能
- 01遵循 Go 语言箴言与惯例
- 02错误添加上下文并妥善处理
- 03避免变量名遮蔽预声明标识符
- 04规定注释与代码行长度
- 05使用 go doc 查询文档
适用场景
- 01统一 Go 项目的代码风格
- 02编写带上下文的错误处理
- 03检查 Go 代码命名和注释
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ fredrikaverpil/ dotfiles --skill golang-style安装后在 Claude Code 中输入/golang-style确认已加载。
详细介绍
Go 编码约定
格言
尽量遵循以下格言:
Go 格言 简洁、优美、精炼 不要通过共享内存来通信,而要通过通信来共享内存。 并发不等于并行。 通道负责协调;互斥锁负责串行化。 接口越大,抽象越弱。 让零值发挥作用。 interface{} 什么也说明不了。 gofmt 的风格不是任何人的最爱,但 gofmt 是所有人的最爱。 少量复制胜过少量依赖。 系统调用必须始终由构建标签保护。 Cgo 必须始终由构建标签保护。 Cgo 不是 Go。 使用 unsafe 包就没有任何保证。 清晰胜过巧妙。 反射永远不清晰。 错误是值。 不要只检查错误,还要妥善处理错误。 设计架构,命名组件,记录细节。 文档是写给用户的。 不要 panic。
编写 Go 代码时,严格遵循这些约定。
顺畅路径编码
组织代码,让成功路径直截了当地向下执行。立即处理错误,然后继续 主要逻辑。
// Correct: happy path flows down.
func ProcessUser(id string) (*User, error) {
user, err := db.GetUser(id)
if err != nil {
return nil, fmt.Errorf("get user %s: %w", id, err)
}
if err := user.Validate(); err != nil {
return nil, fmt.Errorf("validate user %s: %w", id, err)
}
return user, nil
}
// Wrong: main logic nested inside conditions.
func ProcessUser(id string) (*User, error) {
user, err := db.GetUser(id)
if err == nil {
if err := user.Validate(); err == nil {
return user, nil
} else {
return nil, err
}
}
return nil, err
}
错误包装
始终使用 %w 包装错误并提供上下文。包含操作及相关标识符。
// Correct: wrapped with context.
if err != nil {
return fmt.Errorf("create order for customer %s: %w", customerID, err)
}
// Wrong: no context.
if err != nil {
return err
}
哨兵错误
为预期的错误情况定义包级哨兵错误。使用
errors.Is() 进行检查。
// Define at package level.
var (
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrInvalidInput = errors.New("invalid input")
)
// Return sentinel errors.
func GetUser(id string) (*User, error) {
user := db.Find(id)
if user == nil {
return nil, ErrNotFound
}
return user, nil
}
// Check with errors.Is().
user, err := GetUser(id)
if errors.Is(err, ErrNotFound) {
// Handle not found case.
}
注释
所有注释都以句号结尾。
// ProcessOrder handles order creation and validation.
func ProcessOrder(o *Order) error {
// Validate the order before processing.
if err := o.Validate(); err != nil {
return err
}
// Continue with order processing.
return nil
}
命名约定
切勿将 Go 的预声明标识符用作变量或参数名。这些标识符包括可以被遮蔽、但不应被遮蔽的内置函数和常量。
// Wrong: shadows built-in identifiers.
func process(new string, len int, make bool) error {
copy := "data"
return nil
}
// Correct: use descriptive names instead.
func process(name string, length int, shouldCreate bool) error {
dataCopy := "data"
return nil
}
应避免使用的预声明标识符:
- 函数:
new、make、len、cap、append、copy、delete、close、panic、recover、print、println、complex、real、imag、clear、min、max - 常量:
true、false、iota、nil - 类型:
error、bool、string、int、int8、int16、int32、int64、uint、uint8、uint16、uint32、uint64、uintptr、float32、float64、complex64、complex128、byte、rune、any、comparable
行长度
行长最多为 120 个字符。在合理的位置拆分长行。
// Correct: break at logical points.
func ProcessOrderWithValidation(
ctx context.Context,
order *Order,
validator OrderValidator,
) (*Result, error) {
return nil, fmt.Errorf(
"process order %s for customer %s: %w",
order.ID,
order.CustomerID,
err,
)
}
查阅文档
使用 go doc 查阅标准库和软件包的文档:
go doc fmt.Errorf
go doc errors.Is
go doc context
Einride
如果项目隶属于 Einride 组织,始终使用项目中的 Makefile,这些文件由 Sage(.sage 文件夹)生成。
评论
支持 Markdown