go-dev-guidelines
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGo Development Guidelines
Go 开发指南
Overview
概述
This skill provides comprehensive guidelines for idiomatic Go development with a Test-Driven Development (TDD) approach. Follow these patterns when writing Go code, creating tests, organizing projects, or refactoring existing code.
本技能提供了一套基于测试驱动开发(TDD)的地道Go开发综合指南。编写Go代码、创建测试、组织项目或重构现有代码时,请遵循这些模式。
Quick Start Checklists
快速开始检查清单
New Go Feature Checklist
新Go功能检查清单
When implementing a new feature in an existing Go project:
- Define interface - Create small, focused interface in appropriate package
- Write tests first - Create file with testify/require tests
*_test.go - Generate mocks - Use mockery to generate mocks in subfolder
mocks/ - Implement logic - Write the implementation to satisfy tests
- Handle errors - Ensure all errors are explicitly handled
- Add integration tests - Test the feature end-to-end if applicable
- Run go vet & gofmt - Ensure code meets Go standards
- Update documentation - Add godoc comments for exported types/functions
在现有Go项目中实现新功能时:
- 定义接口 - 在合适的包中创建小而聚焦的接口
- 先编写测试 - 创建使用testify/require的测试文件
*_test.go - 生成模拟对象 - 使用mockery在子目录中生成模拟对象
mocks/ - 实现逻辑 - 编写代码以通过测试
- 错误处理 - 确保所有错误都被显式处理
- 添加集成测试 - 若适用,对功能进行端到端测试
- 运行go vet & gofmt - 确保代码符合Go标准
- 更新文档 - 为导出的类型/函数添加godoc注释
New Go Service/Package Checklist
新Go服务/包检查清单
When creating a new Go service or package from scratch:
- Setup project structure - Use standard Go layout (,
/cmd,/internal)/pkg - Initialize module - Run with appropriate module path
go mod init - Define core interfaces - Start with small, focused interfaces
- Write tests first - Follow TDD approach for all business logic
- Implement with DI - Use dependency injection for testability
- Add logging - Include structured logging for observability
- Configure graceful shutdown - Implement proper cleanup for services
- Document package - Add package-level godoc and README
从零开始创建新的Go服务或包时:
- 搭建项目结构 - 使用标准Go布局(,
/cmd,/internal)/pkg - 初始化模块 - 运行并指定合适的模块路径
go mod init - 定义核心接口 - 从创建小而聚焦的接口开始
- 先编写测试 - 所有业务逻辑都遵循TDD流程
- 依赖注入实现 - 使用依赖注入提升可测试性
- 添加日志 - 加入结构化日志以提升可观测性
- 配置优雅停机 - 为服务实现合适的清理逻辑
- 文档化包 - 添加包级godoc注释和README
Core Principles
核心原则
Follow these seven core principles for all Go development:
所有Go开发都需遵循以下7项核心原则:
1. Follow Test-Driven Development (TDD)
1. 遵循测试驱动开发(TDD)
Write tests before implementation. Tests should be easy to read and favor verbosity over abstraction.
先编写测试再实现代码。测试应易于阅读,优先清晰表达而非抽象。
2. Use testify/require for Unit Tests
2. 使用testify/require进行单元测试
All unit tests must use for assertions.
github.com/stretchr/testify/require所有单元测试必须使用进行断言。
github.com/stretchr/testify/require3. Use Mockery for Mocks
3. 使用Mockery生成模拟对象
Generate mocks using mockery. Mocks must be localized in a subfolder next to the interface being mocked.
mocks/使用mockery生成模拟对象。模拟对象必须放在被模拟接口所在目录的子目录中。
mocks/4. Never Use Table-Driven Tests
4. 切勿使用表驱动测试
Avoid table-driven tests. Write explicit test functions for each scenario.
避免使用表驱动测试。为每个场景编写显式的测试函数。
5. Never Mix Positive and Negative Tests
5. 切勿混合正向与负向测试
Keep positive (success) and negative (error) test cases in separate test functions.
将正向(成功)和负向(错误)测试用例放在不同的测试函数中。
6. Handle All Errors Explicitly
6. 显式处理所有错误
Never ignore errors. Always handle them explicitly or return them to the caller.
切勿忽略错误。始终显式处理错误或返回给调用方。
7. Prefer Small, Focused Interfaces
7. 优先选择小而聚焦的接口
Design interfaces with few methods. Use composition over large interfaces.
设计包含少量方法的接口。优先使用组合而非大接口。
8. Use any
Instead of interface{}
anyinterface{}8. 使用any
替代interface{}
anyinterface{}For generic types, prefer over (Go 1.18+).
anyinterface{}对于泛型类型,优先使用而非(Go 1.18+)。
anyinterface{}Standard Go Directory Structure
标准Go目录结构
project-root/
├── cmd/ # Main applications
│ └── myapp/
│ └── main.go
├── internal/ # Private application code
│ ├── handler/ # HTTP handlers
│ │ ├── handler.go
│ │ ├── handler_test.go
│ │ └── mocks/ # Mocks for handler interfaces
│ ├── service/ # Business logic
│ │ ├── service.go
│ │ ├── service_test.go
│ │ └── mocks/
│ └── repository/ # Data access
│ ├── repository.go
│ ├── repository_test.go
│ └── mocks/
├── pkg/ # Public library code
│ └── client/
│ ├── client.go
│ ├── client_test.go
│ └── mocks/
├── api/ # API definitions (OpenAPI, protobuf)
├── configs/ # Configuration files
├── go.mod
├── go.sum
└── README.mdproject-root/
├── cmd/ # 主应用程序
│ └── myapp/
│ └── main.go
├── internal/ # 私有应用代码
│ ├── handler/ # HTTP处理器
│ │ ├── handler.go
│ │ ├── handler_test.go
│ │ └── mocks/ # 处理器接口的模拟对象
│ ├── service/ # 业务逻辑
│ │ ├── service.go
│ │ ├── service_test.go
│ │ └── mocks/
│ └── repository/ # 数据访问
│ ├── repository.go
│ ├── repository_test.go
│ └── mocks/
├── pkg/ # 公共库代码
│ └── client/
│ ├── client.go
│ ├── client_test.go
│ └── mocks/
├── api/ # API定义(OpenAPI, protobuf)
├── configs/ # 配置文件
├── go.mod
├── go.sum
└── README.mdQuick Reference
快速参考
Common Test Patterns
常见测试模式
go
// Unit test with mock
func TestServiceCreate(t *testing.T) {
mockRepo := mocks.NewRepository(t)
mockRepo.On("Save", mock.Anything).Return(nil)
svc := NewService(mockRepo)
err := svc.Create(context.Background(), data)
require.NoError(t, err)
mockRepo.AssertExpectations(t)
}
// Separate negative test
func TestServiceCreate_RepoError(t *testing.T) {
mockRepo := mocks.NewRepository(t)
mockRepo.On("Save", mock.Anything).Return(errors.New("db error"))
svc := NewService(mockRepo)
err := svc.Create(context.Background(), data)
require.Error(t, err)
require.Contains(t, err.Error(), "db error")
}go
// 带模拟对象的单元测试
func TestServiceCreate(t *testing.T) {
mockRepo := mocks.NewRepository(t)
mockRepo.On("Save", mock.Anything).Return(nil)
svc := NewService(mockRepo)
err := svc.Create(context.Background(), data)
require.NoError(t, err)
mockRepo.AssertExpectations(t)
}
// 独立的负向测试
func TestServiceCreate_RepoError(t *testing.T) {
mockRepo := mocks.NewRepository(t)
mockRepo.On("Save", mock.Anything).Return(errors.New("db error"))
svc := NewService(mockRepo)
err := svc.Create(context.Background(), data)
require.Error(t, err)
require.Contains(t, err.Error(), "db error")
}Naming Conventions
命名规范
- Packages: Short, lowercase, no underscores (,
handler)service - Files: Lowercase with underscores (,
user_service.go)user_service_test.go - Types: PascalCase (,
UserService)HTTPHandler - Functions/Methods: PascalCase for exported, camelCase for unexported
- Interfaces: Often end with suffix (
-er,Reader,Writer)UserRepository
- 包名:简短、小写、无下划线(,
handler)service - 文件名:小写加下划线(,
user_service.go)user_service_test.go - 类型:大驼峰命名(,
UserService)HTTPHandler - 函数/方法:导出成员用大驼峰,非导出成员用小驼峰
- 接口:通常以-er后缀结尾(,
Reader,Writer)UserRepository
Navigation Table
导航表
Use this table to find detailed guidance for specific tasks:
| If You Need To... | See This Resource |
|---|---|
| Set up a new Go project structure | Project Structure |
| Understand Go naming conventions | Naming Conventions |
| Write tests with TDD, testify/require, and mockery | Testing Guide |
| Organize packages, interfaces, and dependencies | Code Organization |
| Handle errors idiomatically | Error Handling |
| Work with goroutines, channels, and context | Concurrency Patterns |
| Manage dependencies and go.mod | Dependencies |
| See complete working examples | Complete Examples |
使用下表查找特定任务的详细指南:
| 当你需要... | 请查看此资源 |
|---|---|
| 搭建新Go项目结构 | 项目结构 |
| 了解Go命名规范 | 命名规范 |
| 使用TDD、testify/require和mockery编写测试 | 测试指南 |
| 组织包、接口和依赖 | 代码组织 |
| 地道的错误处理 | 错误处理 |
| 使用goroutine、channel和context | 并发模式 |
| 管理依赖和go.mod | 依赖管理 |
| 查看完整示例 | 完整示例 |
Resources
资源
This skill includes detailed reference documentation in the directory. Claude will load these resources as needed when working on specific tasks.
references/本技能在目录中包含详细的参考文档。Claude在处理特定任务时会按需加载这些资源。
references/