xu-xiang/everything-claude-code-zh
everything-claude-code
February 5, 2026
Select agents to install to:
npx add-skill https://github.com/xu-xiang/everything-claude-code-zh/blob/main/skills/golang-patterns/SKILL.md -a claude-code --skill golang-patternsInstallation paths:
.claude/skills/golang-patterns/# Go 开发模式
用于构建健壮、高效且可维护应用程序的惯用 Go 模式和最佳实践。
## 何时激活
- 编写新的 Go 代码时
- 审查 Go 代码时
- 重构现有的 Go 代码时
- 设计 Go 包(Package)/ 模块(Module)时
## 核心原则
### 1. 简单与清晰
Go 倾向于简单而非巧妙。代码应当直观且易于阅读。
```go
// 推荐:清晰且直接
func GetUser(id string) (*User, error) {
user, err := db.FindUser(id)
if err != nil {
return nil, fmt.Errorf("get user %s: %w", id, err)
}
return user, nil
}
// 不推荐:过于巧妙
func GetUser(id string) (*User, error) {
return func() (*User, error) {
if u, e := db.FindUser(id); e == nil {
return u, nil
} else {
return nil, e
}
}()
}
```
### 2. 使零值(Zero Value)有用
设计类型时,使其零值在无需显式初始化的情况下即可直接使用。
```go
// 推荐:零值是有用的
type Counter struct {
mu sync.Mutex
count int // 零值为 0,可以直接使用
}
func (c *Counter) Inc() {
c.mu.Lock()
c.count++
c.mu.Unlock()
}
// 推荐:bytes.Buffer 的零值即可工作
var buf bytes.Buffer
buf.WriteString("hello")
// 不推荐:需要显式初始化
type BadCounter struct {
counts map[string]int // nil map 会引发 panic
}
```
### 3. 接受接口,返回结构体
函数应当接受接口(Interface)参数并返回具体类型(Concrete Type)。
```go
// 推荐:接受接口,返回具体类型
func ProcessData(r io.Reader) (*Result, error) {
data, err := io.ReadAll(r)
if err != nil {
return nil, err
}
return &Result{Data: data}, nil
}
// 不推荐:返回接口(无谓地隐藏了实现细节)
func ProcessData(r io.Reader) (io.Reader, error) {
// ...
}
```
## 错误处理模式
### 带上下文的错误包装(Error Wrapping)
```go
// 推荐:使用上下文包装错误
func LoadConfig(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("load config %s: %w", path, err)
}
var cfg Config
if err := json.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("parse config %s: %w", path, err)
}
return &cfg, nil
}
```
### 自定义错误类型
```go
// 定义领域特定的错误
type ValidationError struct {
Field string
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("validation failed on %s: %s", e.Field, e.Message)
}
// 常见场景的哨