go-stylelisted
Install: claude install-skill omeyang/Thoth
# Go 代码规范与后端开发专家
审查或编写符合 Go 惯用法的代码:$ARGUMENTS
---
## 第一部分:代码审查检查清单
### 1. 接口设计
```go
// ✅ 正确:接口在使用方定义
// consumer/service.go
type UserFetcher interface {
FetchUser(ctx context.Context, id string) (*User, error)
}
// ❌ 错误:接口在实现方定义
// provider/user.go
type UserService interface { ... } // 不要这样
```
**原则**:
- 接口应在**使用方**定义,而非实现方
- 函数应返回**具体类型**,而非接口(便于扩展)
### 2. 并发安全
```go
// ❌ 危险:无退出策略的 goroutine
go func() {
for {
doWork() // 永远不会退出!
}
}()
// ✅ 正确:有明确退出机制
go func() {
for {
select {
case <-ctx.Done():
return // 有退出路径
case task := <-tasks:
doWork(task)
}
}
}()
```
**检查点**:
- 每个 `go func()` 必须有退出策略(context 或 channel)
- `sync.Mutex` 持有时间是否过长?
- Channel 用于**协调/信号**,Mutex 用于**数据访问**
### 3. 错误处理
```go
// ✅ 正确:使用 %w 包装错误
return fmt.Errorf("parse config: %w", err)
// ✅ 正确:错误字符串小写,无标点
var ErrNotFound = errors.New("user not found")
// ❌ 错误
var ErrNotFound = errors.New("User not found.") // 大写+标点
```
**原则**:
- 使用 `%w` 包装错误以保留错误链
- 错误字符串小写,无结尾标点
- **不要 panic**,除非是不可恢复的启动错误
### 4. 命名规范
```go
// ✅ 正确
var userID string // 驼峰命名
func ServeHTTP() // 缩写全大写
func (s *Server) Run() // 接收者 1-2 字母
// ❌ 错误
var user_id string // 下划线
func ServeHttp() // 缩写不一致
func (server *Server) Run() // 接收者名太长
```
### 5. 复杂度控制
- **清晰 > 聪明**:如果需要思考两次才能理解,就太复杂了
- **避免反射**:除非编写序列化库
- **避免过度抽象**:三行相似代码比过早抽象更好
---
## 第二部分:HTTP 服务开发模式
### 1. Handler 签名模式
标准 `http.Handler` 是 void 返回,导致重复的错误处理。