难点01_调用者接收者

go里c *Gopher(对象的指针)和c Gopher(纯粹对象自己)对应方法集不同(其他语言是同一个类型,java,python,c,c++等,所以方法集自然相同)

对应案例调用方接收方修改效果
1、使用值调用对象+值(纯粹对象)注册到值的方法(这里是 code())不改动原始取值
2、使用指针调用对象+指针
3、使用interface作为调用者interface+指针型注册到指针的方法(这里是 debug())改动原始取值
4、使用interface作为调用者interface+值类型

以上table从接收者视角:值接收者声明的方法能接受值类型和指针类型的参数,指针接收者声明的方法只能接受指针类型的参数。
这一点很容易搞错,比如这篇文章中的举例就是错误的。
典型错误文章,go语言学习:方法:https://blog.csdn.net/weixin_44202489/article/details/105537011
第三部分,三、方法集,中的样例代码都是错误的,(结论对的,样例代码错了)
针对的是上表的第一二种情况。
将文中:类型 *T 方法集包含全部 receiver T + *T 方法。
样例代码:

1
2
3
4
5
6
7
func main() {
t1 := T{1}
t2 := &t1
fmt.Printf("t2 is : %v\n", t2)
t2.testT()
t2.testP()
}

改为

1
2
3
4
5
6
7
8
9
10
func main() {
t1 := T{1}
t2 := &t1
fmt.Printf("t1 is : %v\n", t1)
t1.testT()
t1.testP()
fmt.Printf("t2 is : %v\n", t2)
t2.testT()
t2.testP()
}

也可正常执行,所以可以得到结论:类型 T 方法集包含全部 receiver T + *T 方法?
显然不对了。

案例现象结论
1、使用值调用debug方法成功修改了num的取值,而code没有由值作为接收者,被调用时,是对对象的拷贝,指针作为接收者,被调用时,是对对象本身的操作。
2、使用指针调用,结合案例1、使用值调用可正常运行且输出结果和第一段代码一样不管方法的接收者是什么类型,该类型的值和指针都可以调用,不必严格符合接收者的类型。(案例1和2的调用者Gopher和*Gopher,都属于具体的静态的类型)
3、使用interface作为调用者(interface+指针型)正常编译,输出同上
3、使用interface作为调用者结合 案例4、使用interface作为调用者无法编译interface+值类型,会丧失一部分方法,丧失一部分:注册到指针的方法

参考

go语言结构体定义方法时,值作为接收者和指针作为接收者的区别:https://blog.csdn.net/u014239709/article/details/89552933

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×