307 lines
7.3 KiB
Markdown
307 lines
7.3 KiB
Markdown
# Go语言开发规范
|
||
|
||
本文档定义了Installer Builder项目的Go语言开发规范,旨在提高代码质量、可维护性和一致性。所有项目贡献者和AI代码生成都应遵循这些规范。
|
||
|
||
## 1. 项目结构和代码组织
|
||
|
||
### 1.1 目录结构
|
||
|
||
/
|
||
|
||
├── cmd/ # 命令行入口点
|
||
|
||
│ ├── cli/ # CLI应用
|
||
|
||
│ └── gui/ # GUI应用
|
||
|
||
├── internal/ # 内部包,不对外暴露
|
||
|
||
│ ├── config/ # 配置处理
|
||
|
||
│ ├── builder/ # 构建引擎
|
||
|
||
│ ├── platform/ # 平台适配
|
||
|
||
│ ├── packager/ # 包类型构建器
|
||
|
||
│ ├── script/ # 脚本执行
|
||
|
||
│ └── plugin/ # 插件系统
|
||
|
||
├── pkg/ # 可导出的包,可能被其他项目使用
|
||
|
||
│ ├── api/ # 公共API
|
||
|
||
│ └── schema/ # 配置Schema
|
||
|
||
├── ui/ # GUI相关代码
|
||
|
||
│ ├── frontend/ # Wails前端
|
||
|
||
│ └── assets/ # UI资源
|
||
|
||
├── plugins/ # 插件目录
|
||
|
||
├── examples/ # 示例配置和项目
|
||
|
||
├── scripts/ # 构建和开发脚本
|
||
|
||
└── doc/ # 文档
|
||
|
||
|
||
### 1.2 包设计原则
|
||
|
||
- 每个包应该有单一的职责
|
||
- 避免循环依赖
|
||
- 包名应该简短、清晰,使用小写单词
|
||
- 内部实现细节放在`internal/`目录下
|
||
- 可重用的、稳定的API放在`pkg/`目录下
|
||
|
||
## 2. 命名约定
|
||
|
||
### 2.1 包名
|
||
|
||
- 使用简短、简洁、有意义的名称
|
||
- 使用小写字母,不使用下划线或混合大小写
|
||
- 避免使用常见变量名作为包名(如`util`、`common`等)
|
||
|
||
### 2.2 文件名
|
||
|
||
- 使用小写字母
|
||
- 使用下划线分隔多个单词
|
||
- 测试文件使用`_test.go`后缀
|
||
|
||
### 2.3 变量和常量
|
||
|
||
- 使用驼峰命名法
|
||
- 局部变量使用简短名称
|
||
- 全局变量和常量使用描述性名称
|
||
- 不导出的变量和常量以小写字母开头
|
||
- 导出的变量和常量以大写字母开头
|
||
|
||
### 2.4 函数和方法
|
||
|
||
- 使用驼峰命名法
|
||
- 不导出的函数和方法以小写字母开头
|
||
- 导出的函数和方法以大写字母开头
|
||
- 名称应该表明函数的作用
|
||
- 接收器名称应该简短,通常是类型名称的首字母
|
||
|
||
### 2.5 接口
|
||
|
||
- 单一方法接口名称应以方法名加`er`后缀命名(如`Reader`、`Writer`)
|
||
- 多方法接口应该使用描述其行为的名称
|
||
|
||
### 2.6 结构体
|
||
|
||
- 使用驼峰命名法
|
||
- 不导出的结构体以小写字母开头
|
||
- 导出的结构体以大写字母开头
|
||
- 结构体字段遵循与变量相同的命名规则
|
||
|
||
## 3. 代码风格
|
||
|
||
### 3.1 格式化
|
||
|
||
- 使用`gofmt`或`goimports`自动格式化代码
|
||
- 缩进使用制表符(tab)
|
||
- 行长度建议不超过100个字符
|
||
|
||
### 3.2 导入
|
||
|
||
- 按标准库、第三方包、项目内部包的顺序分组
|
||
- 每组之间用空行分隔
|
||
- 使用点导入(`.`)仅限于测试文件中导入测试包
|
||
|
||
### 3.3 声明
|
||
|
||
- 变量声明尽量靠近使用位置
|
||
- 相关的常量和变量分组声明
|
||
- 使用`var`关键字声明零值变量,使用短声明`:=`声明并初始化变量
|
||
|
||
### 3.4 控制结构
|
||
|
||
- `if`、`for`、`switch`等关键字与左括号之间有一个空格
|
||
- 左大括号不换行
|
||
- `else`、`else if`与右大括号在同一行
|
||
- 避免嵌套过深的控制结构,考虑提前返回
|
||
|
||
## 4. 错误处理
|
||
|
||
### 4.1 错误返回
|
||
|
||
- 错误作为最后一个返回值
|
||
- 使用描述性错误信息
|
||
- 使用`fmt.Errorf`添加上下文信息
|
||
- 考虑使用自定义错误类型和错误包装
|
||
|
||
### 4.2 错误检查
|
||
|
||
- 立即检查错误,避免嵌套
|
||
- 使用`if err != nil`模式
|
||
- 避免使用`_`忽略错误,除非有明确理由
|
||
|
||
### 4.3 错误日志
|
||
|
||
- 在调用栈的适当位置记录错误
|
||
- 避免多次记录同一错误
|
||
- 包含足够的上下文信息
|
||
|
||
### 4.4 错误处理策略
|
||
|
||
- 对于库函数,通常返回错误而不是处理它
|
||
- 对于应用程序,在适当的抽象层处理错误
|
||
- 使用`panic`仅限于不可恢复的情况
|
||
|
||
## 5. 注释规范
|
||
|
||
### 5.1 包注释
|
||
|
||
- 每个包应该有包注释,位于`doc.go`文件或包的主文件中
|
||
- 包注释应该提供包的用途、用法和任何重要的注意事项
|
||
|
||
### 5.2 导出符号注释
|
||
|
||
- 所有导出的函数、类型、常量和变量都应该有注释
|
||
- 注释以符号名称开头,使用完整的句子
|
||
- 遵循`godoc`约定
|
||
|
||
### 5.3 实现注释
|
||
|
||
- 对于复杂的实现,添加注释解释原理和算法
|
||
- 对于不明显的代码,解释为什么这样做,而不仅仅是做了什么
|
||
|
||
### 5.4 TODO和FIXME
|
||
|
||
- 使用`// TODO: `标记计划改进的地方
|
||
- 使用`// FIXME: `标记需要修复的问题
|
||
- 包含足够的上下文信息和可能的解决方向
|
||
|
||
## 6. 测试要求
|
||
|
||
### 6.1 测试覆盖率
|
||
|
||
- 核心功能应该有单元测试
|
||
- 目标测试覆盖率至少70%
|
||
- 关键路径和边界条件必须测试
|
||
|
||
### 6.2 测试组织
|
||
|
||
- 使用表驱动测试
|
||
- 测试文件与被测试文件放在同一目录
|
||
- 使用`_test.go`后缀命名测试文件
|
||
|
||
### 6.3 测试命名
|
||
|
||
- 测试函数命名为`Test<Function>`
|
||
- 基准测试命名为`Benchmark<Function>`
|
||
- 示例测试命名为`Example<Function>`
|
||
|
||
### 6.4 测试工具
|
||
|
||
- 使用标准库的`testing`包
|
||
- 可以使用`testify`等辅助库提高测试效率
|
||
- 使用`go test -race`检测竞态条件
|
||
|
||
## 7. 依赖管理
|
||
|
||
### 7.1 依赖选择
|
||
|
||
- 优先使用标准库
|
||
- 选择活跃维护、文档完善的第三方库
|
||
- 避免引入过多依赖
|
||
|
||
### 7.2 版本控制
|
||
|
||
- 使用Go Modules进行依赖管理
|
||
- 在`go.mod`中明确指定依赖版本
|
||
- 定期更新依赖以获取安全修复
|
||
|
||
### 7.3 依赖隔离
|
||
|
||
- 考虑使用接口隔离第三方依赖
|
||
- 为核心功能编写适配器,便于将来替换依赖
|
||
|
||
## 8. 并发处理
|
||
|
||
### 8.1 并发模式
|
||
|
||
- 优先使用高级并发原语(如`sync.WaitGroup`、通道)
|
||
- 避免共享内存,通过通信共享
|
||
- 使用适当的同步机制保护共享资源
|
||
|
||
### 8.2 Goroutine管理
|
||
|
||
- 确保所有启动的goroutine都能正确终止
|
||
- 使用上下文(`context.Context`)传递取消信号
|
||
- 避免goroutine泄漏
|
||
|
||
### 8.3 并发安全
|
||
|
||
- 明确标记非并发安全的类型和函数
|
||
- 使用`sync/atomic`包进行原子操作
|
||
- 使用`-race`标志测试并发代码
|
||
|
||
## 9. 日志记录
|
||
|
||
### 9.1 日志级别
|
||
|
||
- 使用适当的日志级别(Debug、Info、Warning、Error、Fatal)
|
||
- 在开发环境和生产环境使用不同的日志级别
|
||
|
||
### 9.2 日志内容
|
||
|
||
- 包含足够的上下文信息
|
||
- 避免记录敏感信息
|
||
- 使用结构化日志便于分析
|
||
|
||
### 9.3 日志接口
|
||
|
||
- 使用抽象的日志接口,便于将来替换日志实现
|
||
- 考虑使用`uber-go/zap`或`sirupsen/logrus`等成熟的日志库
|
||
|
||
## 10. 代码审查清单
|
||
|
||
### 10.1 功能性
|
||
|
||
- 代码是否实现了预期功能
|
||
- 是否处理了所有边界条件
|
||
- 错误处理是否完善
|
||
|
||
### 10.2 可维护性
|
||
|
||
- 代码是否易于理解
|
||
- 是否有适当的注释
|
||
- 是否遵循项目的代码风格
|
||
|
||
### 10.3 性能
|
||
|
||
- 是否有明显的性能问题
|
||
- 是否有不必要的计算或内存分配
|
||
- 并发代码是否正确且高效
|
||
|
||
### 10.4 安全性
|
||
|
||
- 是否有安全漏洞
|
||
- 是否正确处理用户输入
|
||
- 是否泄露敏感信息
|
||
|
||
## 11. AI代码生成指南
|
||
|
||
### 11.1 代码生成原则
|
||
|
||
- 生成的代码应遵循本文档中的所有规范
|
||
- 优先生成简洁、可读性高的代码
|
||
- 包含适当的注释和文档
|
||
|
||
### 11.2 代码生成提示
|
||
|
||
- 明确指定需要生成的功能和接口
|
||
- 提供足够的上下文信息
|
||
- 指定任何特殊要求或约束
|
||
|
||
### 11.3 代码审查
|
||
|
||
- 生成的代码应经过人工审查
|
||
- 检查是否符合项目规范
|
||
- 验证功能正确性和性能 |