GO:值接收者和指针接收者的区别
虽然我们之前提到过,在使用S.F()方式调用方法时,GO对值和指针的限制是宽松的,但是在继承接口这方面,这里是有着严格的区分的。
1. 实现接口的函数接收者全是值,使用值调用
type I interface {
M()
M2()
}
type S struct {
number int64
}
func (s S) M() {
fmt.Println(s.number)
}
func (s S) M2() {
fmt.Println(s.number)
}
func F(i I) {
i.M()
i.M2()
}
func main() {
s := S{number: 64}
F(s)
}
这里所有的M()函数接受者都是值,因此F(s)是没问题的
2. 实现接口的函数接收者部分是值,使用值调用
修改上面的函数定义:
func (s *S) M2() {
fmt.Println(s.number)
}
这里的M2()接收者改成了指针,F(s)就不能调用了,因为S的值现在不算实现了I接口。
3. 实现接口的函数接收者全是指针,使用指针调用
这种情况显然是成立的,不贴代码了。
4. 实现接口的函数接收者部分是指针,使用指针调用
type I interface {
M()
M2()
}
type S struct {
number int64
}
func (s S) M() {
fmt.Println(s.number)
}
func (s *S) M2() {
fmt.Println(s.number)
}
func F(i I) {
i.M()
i.M2()
}
func main() {
s := &S{number: 64}
F(s)
}
这里也是能正常调用的。
5. 实现接口的函数接收者全是值,使用指针调用
type I interface {
M()
M2()
}
type S struct {
number int64
}
func (s S) M() {
fmt.Println(s.number)
}
func (s S) M2() {
fmt.Println(s.number)
}
func F(i I) {
i.M()
i.M2()
}
func main() {
s := &S{number: 64}
F(s)
}
这里依然能够正常调用。
综上所述,在没有特殊要求的情况下,统一使用指针作为接收者是最好的选择。
标签:number,接收者,Println,func,M2,GO,指针 From: https://www.cnblogs.com/smartljy/p/18622026