
在go中,接收器是方法所属的类型实例(类似c#的this),而参数是显式传入的值;接收器决定方法归属和调用绑定方式,参数仅用于传递数据。二者在语义、作用域和绑定时机上存在本质差异。
在Go语言中,接收器(receiver) 和 参数(parameter) 虽然都出现在函数签名中,但扮演完全不同的角色:
-
接收器:定义方法“属于谁”。它紧接在func关键字之后、方法名之前,语法为(r ReceiverType)或(r *ReceiverType)。它不是函数的输入参数,而是方法调用的主体——即调用该方法的变量本身。例如:
type Page struct { Title string Body []byte } func (p *Page) Save() error { // ← p 是接收器,代表被调用的 *Page 实例 filename := p.Title + ".txt" return ioutil.WriteFile(filename, p.Body, 0600) } // 调用时: p := &Page{Title: "Home", Body: []byte("Hello")} p.Save() // ← p 是接收器,无需显式传入;Save() 无参数此处 p 并非普通参数,而是方法上下文中的“所有者”,编译器自动将调用者绑定到该标识符。
-
参数:位于方法名后的括号内,是显式传入的数据,用于补充方法执行所需的信息。例如:
立即学习“go语言免费学习笔记(深入)”;
func (p *Page) SaveAs(filename string) error { // ← filename 是参数 return ioutil.WriteFile(filename, p.Body, 0600) } p.SaveAs("backup.txt") // ← "backup.txt" 是实参,对应形参 filename
关键区别在于绑定时机与多态机制:
✅ 接收器类型(尤其是接口类型)直接影响方法集和动态分派——若接收器是接口(如 func (r io.Reader) Read(...)),实际调用的方法由运行时具体类型决定(类似虚函数);
❌ 参数永远是静态类型,不参与方法查找或接口实现判定。
⚠️ 注意事项:
- 接收器可以是值类型或指针类型,影响是否能修改原值(指针接收器可修改字段,值接收器操作副本);
- 同一类型的所有方法必须保持接收器一致性(全用值或全用指针)以避免意外的接口实现缺失;
- 接收器名称(如p)仅在方法体内可见,不占用外部命名空间,也不参与导出规则。
简言之:接收器回答“谁在做事”,参数回答“还要做什么事”。理解这一区分,是掌握Go面向对象设计、接口实现与方法集规则的基础。










