go中结构体方法接收器应选指针类型:需修改字段、结构体较大或涉及接口实现时必须用指针;小结构体且只读时可用值接收器,但须保持方法集一致。

Go 里没有“成员函数”,只有方法(method)
Go 不支持类和成员函数的概念,所谓“结构体函数绑定”实际是给类型定义 method,它必须显式声明接收者(receiver)。接收者不是隐式的 this 或 self,漏写或写错就编译失败。
- 接收者必须是**当前包定义的类型**,或该类型的指针——不能为内置类型(如
[]int、map[string]int)直接加方法 - 接收者类型要和调用方一致:用
MyStruct{}调用,接收者就得是MyStruct;用&MyStruct{}调用,接收者就得是*MyStruct - 如果方法要修改结构体字段,接收者必须是指针类型(
*MyStruct),值类型接收者修改的是副本,原结构体不变
正确声明结构体方法的语法格式
方法声明看起来像函数,但多了一个接收者参数段,放在 func 关键字和名字之间:
func (s MyStruct) GetName() string {
return s.name
}
func (s *MyStruct) SetName(n string) {
s.name = n // 这里能改原结构体
}
- 接收者变量名(如
s)建议简短、有意义,不强制用self或this - 接收者类型若为指针,
MyStruct和*MyStruct被视为两种不同类型,方法不互通 - 同一个类型上不能同时存在
(s MyStruct)和(s *MyStruct)的同名方法,否则编译报错:method redeclared
为什么调用时有时能自动取地址、有时不行?
Go 编译器会做隐式转换,但仅限于“可寻址值”:
- 变量(如
var u User)是可寻址的 → 调用(*User).Method时,Go 自动转成&u.Method() - 字面量(如
User{})、函数返回值(如newUser()返回User)不可寻址 → 若方法接收者是*User,则User{}.Method()报错:cannot call pointer method on User literal - 数组/切片元素、map 中的 struct 值也默认不可寻址,需先赋给变量再调用指针方法
嵌入结构体时方法“继承”的真实行为
嵌入(embedding)不是继承,只是字段提升(field promotion);方法提升只发生在**可导出字段**且**接收者匹配**时:
-
type A struct{ B }中,若B是导出类型(B首字母大写),且B有func (b B) Foo(),那么a.Foo()可用(前提是a是A值类型,B方法也是值接收者) - 若
B的方法接收者是*B,而A字段是B(非指针),则a.Foo()无法调用——因为A中的B字段不可取地址 - 解决办法:把嵌入字段改为
*B,或确保调用方是*A类型(这样内部B字段才可寻址)
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











