Files
cs-note/hzh/GolangStar/Go语言基础/Go语言命名规范.md
T

168 lines
4.4 KiB
Markdown

---
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语言结构体]]