# 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` - 基准测试命名为`Benchmark` - 示例测试命名为`Example` ### 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 代码审查 - 生成的代码应经过人工审查 - 检查是否符合项目规范 - 验证功能正确性和性能