命名规则 - Go 语言的命名约定

← 返回基础概念

良好的命名是代码可读性的基础。Go 语言有一套简洁明确的命名规则。

核心规则

命名可见性

Go 通过标识符首字母大小写控制访问权限:

// 公开(导出)- 首字母大写
type User struct {
    Name string  // 公开字段
    email string // 私有字段
}

func GetUser() string {  // 公开函数
    return "user"
}

func getUser() string {  // 私有函数
    return "user"
}

规则 首字母大写 = 公开(可导出)首字母小写 = 私有(包内可见)

命名约定

包名

// ✅ 推荐:简短、小写、单个单词
package fmt
package http
package strings

// ❌ 避免:下划线、混合大小写、过长
package my_package
package myPackage
package verylongpackagename

变量名

// ✅ 推荐:驼峰命名法
userName := "Go"
isValid := true
totalCount := 100

// ❌ 避免:下划线命名(非 Go 惯用法)
user_name := "Go"
is_valid := true

常量名

// ✅ 推荐:驼峰命名法
const maxRetries = 3
const defaultTimeout = 30

// ✅ 特殊情况:枚举常量可使用前缀
const (
    LevelDebug = iota
    LevelInfo
    LevelError
)

函数名

// ✅ 推荐:动词或动词短语,驼峰命名
func getUser() string { }
func validateInput() bool { }
func processData() { }

// ✅ 接口方法命名
type Reader interface {
    Read(p []byte) (n int, err error)  // 单一方法通常用动词
}

type Stringer interface {
    String() string  // 转换方法通常用 er 结尾的名词
}

接口名

// ✅ 单方法接口:方法名 + er 后缀
type Reader interface {
    Read([]byte) (int, error)
}

type Writer interface {
    Write([]byte) (int, error)
}

// ✅ 多方法接口:描述性名称
type ReadWriter interface {
    Reader
    Writer
}

type HttpClient interface {
    Get(url string) (Response, error)
    Post(url string, body []byte) (Response, error)
}

缩写规则

常见缩写处理

// ✅ 推荐:缩写词首字母大写,其余小写
type HttpServer struct {}   // 不是 HTTPServer
type XmlDocument struct {}  // 不是 XMLDocument
type UserId int             // 不是 UserID

var apiUrl string           // 不是 APIURL
var xmlContent []byte       // 不是 XMLContent
常见缩写词
  • Http → Http
  • Xml → Xml
  • Json → Json
  • Id → Id
  • Url → Url
  • Sql → Sql

命名最佳实践

1. 简洁胜于冗长

// ✅ 简洁清晰
func (r *Request) Write() { }
type User struct { }

// ❌ 过度冗长
func (r *HttpRequest) WriteToResponse() { }
type UserAccount struct { }

2. 语境优先

// ✅ 在 User 结构体内,不需要重复前缀
type User struct {
    Name     string
    Email    string
    Password string
}

// ❌ 避免
type User struct {
    UserName     string
    UserEmail    string
    UserPassword string
}

3. 有意义的命名

// ✅ 清晰表达意图
func isActive() bool { }
const maxConnections = 100

// ❌ 含义模糊
func check() bool { }
const n = 100

State vs Status

核心区别

类型含义使用场景示例
State单一状态值枚举、布尔值On/Off, Running/Paused
Status位运算组合一个值表达多个状态1<<0 | 1<<2

State - 单一状态

表示某个时刻的单一状态

// State - 单一状态枚举
type State int
const (
    StateOff State = iota
    StateOn
    StatePaused
)

Status - 位运算组合

使用位运算将多个 state组合成一个值。

// Status - 位运算组合多个状态
type Status uint32

const (
    StatusReady     Status = 1 << iota  // 1
    StatusRunning                       // 2
    StatusPaused                        // 4
    StatusError                         // 8
    StatusCompleted                     // 16
)

// 检查状态
if status&StatusRunning != 0 {
    // 正在运行
}

// 组合多个状态
status := StatusReady | StatusRunning  // 3

记忆 State = 单一状态 / Status = 位运算组合多状态

快速判断

场景对照

场景使用示例
开关状态boolEnabled, Active
模式选择StateStateOn/Off/Paused
多状态组合StatusStatusReady | StatusRunning
权限标志StatusRead | Write | Execute

时间字段命名

核心原则

含义命名类型示例
事件时刻At 后缀int64CreatedAt, UpdatedAt
时间值Time 后缀time.TimeStartTime, EndTime
持续时间Durationtime.DurationTimeout, Delay
过期时间ExpiresAtint64ExpiresAt
// ✅ 推荐:At 后缀表示时间点(Unix 时间戳)
type User struct {
    CreatedAt int64  // 创建时间(Unix 秒)
    UpdatedAt int64  // 更新时间(Unix 秒)
    DeletedAt int64  // 删除时间(0 表示未删除)
}

// Time 后缀使用 time.Time
type Event struct {
    StartTime time.Time
    EndTime   time.Time
}

// 持续时间(Duration 仍用 time.Duration)
type Task struct {
    Duration time.Duration  // 持续时长
    Timeout  time.Duration  // 超时时长
}

类型选择

后缀推荐类型允许类型说明
Atint64int64, uint64, int32, uint32Unix 时间戳(秒或毫秒)
Timetime.Timetime.TimeGo 原生时间类型
Durationtime.Durationtime.Duration持续时间

注意 At 后缀用 int64 时间戳,Time 后缀用 time.Time

零值处理

// 使用 0 表示未设置
type User struct {
    DeletedAt int64  // 0 = 未删除,非 0 = 删除时间戳
}

// 检查是否已删除
if user.DeletedAt != 0 {
    // 已删除
}

// 使用负数表示特殊含义(可选)
const TimestampNotSet = -1

type Order struct {
    PaidAt int64  // -1 = 未支付,0 = 未知,>0 = 支付时间
}

记忆 At 用 int64 时间戳,Time 用 time.Time,Duration 用 time.Duration

常见错误

错误1:使用下划线命名

// ❌ Go 风格
var user_name string

// ✅ Go 惯用法
var userName string

错误2:私有字段使用大写开头

// ❌ 错误:看似私有但实际导出
type User struct {
    Name string
    Password string  // 大写开头,其他包可访问
}

// ✅ 正确
type User struct {
    Name     string
    password string  // 小写开头,包内私有
}

错误3:过度使用缩写

// ❌ 难以理解
var usrCnt int
func procData() { }

// ✅ 清晰明确
var userCount int
func processData() { }

命名决策树

快速参考

类型规则示例
包名小写、简短package http
公开标识符首字母大写func GetUser()
私有标识符首字母小写func getUser()
变量/常量驼峰命名userName, maxCount
接口动词+er 或描述性Reader, HttpClient
缩写词首字母大写HttpServer, userId
单一状态State / bool枚举或布尔
组合状态Status位运算组合多个状态
时间点At 后缀int64 时间戳
时间值Time 后缀time.Time
持续时间Durationtime.Duration

← 返回基础概念 | 继续:声明与初始化 →