--- tags: [go, golang, go基础语法, go命名规范] create time: 2026-06-07 15:00 --- # Go 语言命名规范 ## 概述 Go 的命名哲学可以概括为一句话:**一眼就能看懂,无需猜测。** 本文总结包名、文件名、变量、函数、结构体、接口等所有标识符的命名规则。 ## 正文 ### 核心原则:大小写决定可见性 Go 没有 `public` / `private` 关键字,而是用**首字母大小写**来控制导出: > [!note] 📝 导出规则(最重要的一条) > - **大写开头** → 导出(exported),其他包可访问 > - **小写开头** → 未导出(unexported),仅限本包内部使用 ```go package mathClass // Add 导出 → 其他包可调用 func Add(x, y int) int { return x + y } // sub 未导出 → 仅在 mathClass 包内可用 func sub(x, y int) int { return x - y } ``` > [!question] ❓ 思考 > 如果两个包分别导入了同一个第三方库,其中一个包的某个函数名和标准库重名,会发生什么? ### 包名 | 规则 | 示例 | |------|------| | 全小写,无下划线,简短有意义 | `package domain` / `package service` | | 尽量与目录名一致 | 目录 `user/` → `package user` | | 不与标准库重名 | 不要用 `package fmt` | ### 文件名 - 全小写,可用下划线分隔(但建议少用) - 头尾不能有下划线 - 避免与系统保留后缀冲突 > [!warning] ⚠️ 特殊文件后缀 | 后缀 | 含义 | |------|------| | `_test.go` | 测试文件,不编译到正常构建中 | | `_windows.go` / `_linux.go` | 平台特定文件,按 GOOS 条件编译 | | `_386.go` / `_amd64.go` | 架构特定文件,按 GOARCH 条件编译 | > [!tip] 💡 实用建议 > 虽然 Go 允许文件名含下划线,但为了整洁和避免踩坑,**能不用就不用**。多个单词用驼峰或连字符替代。 ### 常量 & 枚举 采用驼峰命名,按功能分组: ```go const ( TypePage = "page" // 页面类型 TypeHome = "home" TypeSection = "section" TypeTaxonomy = "taxonomy" // 临时状态 TypeUnknown = "unknown" ) ``` 枚举型常量应先定义类型,再用 `iota` 递增: ```go type CompareType int const ( TypeEq CompareType = iota TypeNe TypeGt TypeGe TypeLt TypeLe ) ``` > [!tip] 💡 iota 分组技巧 > 用空行分隔不同用途的 `iota` 序列,每个序列重新从 0 开始,可读性更好。 ### 变量名 - 驼峰命名,首字母根据导出需求定大小写 - **布尔变量**以 `Is` / `Has` / `Can` / `Allow` 开头 ```go var isExist bool var hasConflict bool var canManage bool var allowGitHook bool ``` > [!warning] ⚠️ 常见陷阱 > 布尔变量不要起成 `valid`、`ok` 这种含糊的名字——读者无法从名字判断它是什么状态的布尔值。 ### 结构体名 驼峰命名,多字段时用多行声明更清晰: ```go type ServiceConfig struct { Port string `json:"port"` Address string `json:"address"` } config := ServiceConfig{ Port: "8080", Address: "111.222.333.444", } ``` > [!tip] 💡 初始化风格 > 字段超过 2 个时,推荐用**键值初始化**(如上),比位置初始化更不易出错。 ### 接口名 单方法接口的命名惯例是**词根 + er**: | 接口 | 方法 | 含义 | |------|------|------| | `Reader` | `Read(p []byte) (n int, err error)` | 读取器 | | `Writer` | `Write(p []byte) (n int, err error)` | 写入器 | | `Closer` | `Close() error` | 关闭器 | | `Seeker` | `Seek(offset int64, whence int) (int64, error)` | 定位器 | ```go type Reader interface { Read(p []byte) (n int, err error) } ``` > [!note] 📝 为什么是 "er" 后缀? > 这是 Go 社区约定俗成的惯例,源自 stdlib。遵循它能让你写的接口与其他库无缝对接(比如 `io.Reader` 可以被任何 `fmt.Fprint` 消费)。 ### 函数名 - 驼峰命名,首字母控制导出 - 名称应为**动词或动词短语**,简洁准确 ```go func Save() {} // 导出:保存 func doJob() {} // 未导出:执行任务 func GetUser(id) {} // 导出:获取用户 ``` > [!warning] ⚠️ 注意 > 函数名不要与标准库函数重名,否则会造成混淆,甚至编译错误。 ## 关联笔记 - [[hzh/GolangStar/Go语言基础/Go语言代码结构]] - [[hzh/GolangStar/Go语言基础/Go语言变量]] - [[hzh/GolangStar/Go语言基础/Go语言结构体]]