References: Effective Go, Go Code Review Comments, uber-go/guide
Toolchain
goimports -w . # 格式化并整理 import
go vet ./... # 静态分析
golangci-lint run # 综合检查
go test -v -race -cover ./... # 测试(含竞态检测和覆盖率)
Naming Conventions
| Type | Rule | Example |
|---|---|---|
| Package name | Lowercase words, no underscores | user, orderservice |
| Variables/Functions | CamelCase, consistent casing for abbreviations | userID, HTTPServer |
| Constants | Exported use CamelCase, unexported may use CamelCase or all caps | MaxRetryCount |
| Interfaces | Single-method interfaces use method name + er | Reader, Writer |
Prohibited: common, util, base and other meaningless package names
import order
import (
"context" // 标准库
"fmt"
"github.com/gin-gonic/gin" // 第三方库
"project/internal/model" // 项目内部
)
Error Handling
Errors must be handled, cannot be ignored:
// ✅ 好:添加上下文
if err != nil {
return fmt.Errorf("failed to query user %d: %w", userID, err)
}
// ❌ 差:忽略错误
result, _ := doSomething()
Error wrapping: use %w to preserve the error chain, use errors.Is() / errors.As() to check
Concurrent Programming
Basic principles:
- Prefer channel communication
- Before starting a goroutine, consider: who will wait for it? How will it be stopped?
- Use
context.Contextto control the lifecycle
// ✅ 好:使用 context 控制
func process(ctx context.Context) error {
done := make(chan error, 1)
go func() { done <- doWork() }()
select {
case err := <-done:
return err
case <-ctx.Done():
return ctx.Err()
}
}
Data race: use go test -race to detect
Testing Standards
// 表驱动测试
func TestAdd(t *testing.T) {
tests := []struct {
name string
a, b int
expected int
}{
{"positive", 1, 2, 3},
{"zero", 0, 0, 0},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Add(tt.a, tt.b)
if got != tt.expected {
t.Errorf("Add(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.expected)
}
})
}
}
Performance Optimization
| Pitfall | Solution |
|---|---|
| Concatenating strings in a loop | Use strings.Builder |
| Slice not preallocated | make([]T, 0, cap) |
| N+1 query | Batch query + preload |
| Unlimited concurrency | Use semaphore or worker pool |
| Raw SQL alias uses a reserved word | Avoid using year_month/order/status/rank and other MySQL reserved words as aliases |
# 性能分析
go test -cpuprofile=cpu.prof -bench=.
go tool pprof cpu.prof
Project Structure
project/
├── cmd/ # 可执行文件入口
├── internal/ # 私有代码
│ ├── handler/
│ ├── service/
│ ├── repository/
│ └── model/
├── pkg/ # 公共代码
├── go.mod
└── go.sum
Detailed References
| File | Content |
|---|---|
references/go-style.md |
Naming conventions, error handling, concurrency, testing, performance |
references/date-time.md |
Date addition/subtraction, billing period calculation, AddDate overflow handling |
📋 This reply follows:
go-dev- [specific section]