- 值接收器: 当方法为值接收器时,它会在方法的每次调用时都操作结构体的一个副本。这意味着对结构体字段的任何修改都不会反映到原始结构体上。
type Dog struct{}
func (d Dog) Eat() {}
- 指针接收器: 当方法为指针接收器时,它直接作用于原始的结构体实例上,允许方法内部对结构体的修改影响到原始数据。
type Dog struct{}
func (d *Dog) Eat() {}
下面有四个示例,
- 示例一和示例三是值接收器
- 示例二和示例四是值接收器
- 示例一和示例二是值初始化
- 示例三和示例四是指针初始化
示例一 正常
type Animals interface {
Eat()
}
type Dog struct{}
func (d Dog) Eat() {}
func main() {
var a Animals = Dog{}
a.Eat()
}
示例二 报错
type Animals interface {
Eat()
}
type Dog struct{}
func (d *Dog) Eat() {}
func main() {
var a Animals = Dog{}
a.Eat()
}
示例三 正常
type Animals interface {
Eat()
}
type Dog struct{}
func (d Dog) Eat() {}
func main() {
var a Animals = &Dog{}
a.Eat()
}
示例四 正常
type Animals interface {
Eat()
}
type Dog struct{}
func (d *Dog) Eat() {}
func main() {
var a Animals = &Dog{}
a.Eat()
}
通过上面的测试,发现 指针接收器通过值初始化会报错
执行go build -gcflags -S main.go可以看到程序的汇编代码
接下来看看实例一的汇编代码,示例一是值接收器,但是在汇编代码中是有对指针接收器的方法的
说明值接收器的方法会默认添加到指针接收器上一份
指针接收器的方法不会给值接收器添加
结论
- 值接收器的方法可以,值类型和指针类型都可以调用,因为会给指针接收器也添加上方法
- 指针接收器的方法不能通过值类型实例直接调用,因为值接收器上没有接口方法,这会涉及到类型不匹配的问题。