
Go 不禁止用 this 作为方法接收者名称,但官方明确反对——因其违背 Go 强调显式性、函数式思维和类型语义的设计哲学,易引发对值/指针行为的误解,损害代码可读性与协作一致性。
go 不禁止用 `this` 作为方法接收者名称,但官方明确反对——因其违背 go 强调显式性、函数式思维和类型语义的设计哲学,易引发对值/指针行为的误解,损害代码可读性与协作一致性。
在 Go 中,方法本质上是“绑定到类型的函数”,而非传统面向对象语言中“属于类的成员函数”。接收者(receiver)并非语法糖下的隐式上下文(如 Java 的 this 或 Python 的 self),而是显式声明的第一个参数。这一点可通过 Go 的等价调用形式直观印证:
type User struct {
Name string
}
func (u *User) UpdateName(name string) {
u.Name = name
}
func main() {
u := &User{Name: "Alice"}
// 两种调用方式语义完全等价
u.UpdateName("Bob") // 语法糖写法
(*User).UpdateName(u, "Bob") // 显式函数调用:receiver 作为首参传入
}
这段代码清晰表明:u 不是魔法变量,而是普通参数;(*User).UpdateName 是一个真实存在的函数,u 是它被调用时传入的第一个实参。若将其命名为 this,不仅无法传达其实际角色(如 *User 实例),反而会错误暗示“总是指向当前对象”的 OOP 语义——而这在 Go 中并不存在。
更关键的是,Go 的接收者可为值类型或指针类型,二者语义截然不同:
func (u User) Clone() User { // ✅ 值接收者:操作副本,不影响原值
return u
}
func (u *User) Reset() { // ✅ 指针接收者:可修改原值
u.Name = ""
}
若统一使用 this:
- func (this User) Clone() 会误导读者认为 this.Name = "x" 能修改调用方原实例(实际不能);
- func (this *User) Reset() 则模糊了 * 所承载的关键信息:可变性依赖于指针语义,而非名称本身。
因此,Go 官方《Code Review Comments》明确指出:
❌ Don’t use generic names such as "me", "this" or "self" — identifiers typical of object-oriented languages that place more emphasis on methods as opposed to functions.
✅ 推荐实践如下:
- 简短、小写、具类型提示性:用 u 表示 *User,s 表示 Service,r 表示 Reader,c 表示 Config;
- 保持一致性:同一包内,相同类型应使用相同缩写(如 u *User 和 u User 都用 u);
- 必要时增强语义:对复杂类型可适度扩展,如 cfg Config、srv *Server,但需以提升可读性为前提,避免冗余;
- 导出方法必须注释:VS Code 提示的 exported method should have comment 是强制规范,注释应说明功能、副作用及返回值含义。
最后需强调:禁用 this 并非语法限制,而是 Go 社区历经多年沉淀形成的工程共识。它服务于一个核心目标——让代码无需注释即可自解释,让新人一眼理解数据流向与内存行为,让团队协作摆脱命名歧义带来的沟通成本。坚持这一约定,写出的才是地道、健壮、可维护的 Go 代码。











