
go 语言中接口命名应遵循“单方法接口用动词 + er”惯例(如 reader、writer),多方法接口则需体现其核心职责(如 net.conn),避免生硬拼接或冗余前缀(如 i- 或 -er 堆砌)。
go 语言中接口命名应遵循“单方法接口用动词 + er”惯例(如 reader、writer),多方法接口则需体现其核心职责(如 net.conn),避免生硬拼接或冗余前缀(如 i- 或 -er 堆砌)。
在 Go 中,接口命名不是语法要求,而是社区长期形成的强约定(idiomatic Go),直接影响代码的可读性、可维护性与协作效率。核心原则有三:
✅ 单方法接口:优先使用 Verb + er 模式
这是 Go 最经典、最被广泛接受的命名方式,源自标准库并被《Effective Go》和官方文档明确推荐:
type Reader interface {
Read(p []byte) (n int, err error)
}
type Closer interface {
Close() error
}
type Stringer interface {
String() string
}
即使拼写略显生硬(如 Execer),也优于 Executor 或 IExecutor——因为 Executor 易与具体实现类型混淆,而 IExecutor 是典型的 C++/Java 风格,在 Go 中被视为反模式。
⚠️ 注意:仅当方法语义与标准库中同名方法完全一致时,才复用该名称(如 String() 必须返回 string 且无副作用)。否则应另选更准确的名称,避免误导。
✅ 多方法接口:按职责命名,拒绝拼凑
当你需要组合多个行为(如 IsRole + AssumeRole),不应强行合并为 RoleCheckerAssumer——这违反了命名的“可读性第一”原则。更合理的做法是:
-
按抽象层级拆分:
type RoleChecker interface { IsRole(target Role, hierarchy RolesHierarchy) bool } type RoleAssumer interface { AssumeRole(session ServerSession, role Role) } -
或定义单一职责的聚合接口(若二者逻辑强绑定):
// 名称体现能力本质,而非方法罗列 type RoleManager interface { IsRole(target Role, hierarchy RolesHierarchy) bool AssumeRole(session ServerSession, role Role) }RoleManager 比 RoleCheckerAssumer 更自然、更具领域语义,也便于未来扩展(如增加 RevertRole())。
❌ 避免的命名陷阱
- ServerSessioner:Session 不是动词,“-er”后缀在此无意义,且易被误读为“使 Session 的人”。✅ 正确命名是 Session(简洁)或 ServerSession(若需区分客户端会话)。
- Roler:Role 是名词,Roler 语义模糊(指“扮演角色的人”?还是“提供角色能力的对象”?),不符合 Go 接口命名以行为(behavior)为中心的设计哲学。
- I* 前缀(如 IRoleChecker):Go 不采用 COM/C# 的接口标识惯例;所有类型(包括接口)都是一等公民,无需语法标记。
? 额外建议:接收者命名一致性
你代码中的 this 和 self 风格需修正。Go 推荐使用短小、类型导向的接收者名,例如:
func (r Role) IsRole(target Role, hierarchy RolesHierarchy) bool { ... } // ✅ r 表示 Role
func (r *Role) AssumeRole(session ServerSession, role Role) { ... } // ✅ 保持 r 一致
// 而非 func (this *Role) ... 或 func (self *Role) ...
这不仅符合 Go 官方 Code Review 规范,还能显著提升方法内代码的紧凑性与可读性。
综上,接口命名的本质是通过名称即刻传达“它能做什么”。与其纠结语法奇巧,不如回归接口的契约本质:用最简练、最无歧义的英文名词,精准概括一组行为的抽象意图。











