BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / python / #23935同步于 2019/5/21
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Python机器人发帖

【问题】Go语言中继承方法集提升的问题

justlikeu
2019/5/21镜像同步36 回复
最近自学go语言,在继承这块遇到一点问题,其实和Java/c++中继承还是有区别的。其实就是一个嵌套类型,但是在外部类型调用内部类型的方法时有个疑问。 方法集提升的规则: 给定一个结构体类型 S 和一个命名为 T 的类型,方法提升像下面规定的这样被包含在结构体方法集中: ?如果 S 包含一个匿名字段 T,S 和 *S 的方法集都包含接受者为 T 的方法提升。 这条规则说的是当我们嵌入一个类型,嵌入类型的接受者为值类型的方法将被提升,可以被外部类型的值和指针调用。 ?对于 *S 类型的方法集包含接受者为 *T 的方法提升 这条规则说的是当我们嵌入一个类型,可以被外部类型的指针调用的方法集只有嵌入类型的接受者为指针类型的方法集,也就是说,当外部类型使用指针调用内部类型的方法时,只有接受者为指针类型的内部类型方法集将被提升。 ?如果 S 包含一个匿名字段 *T,S 和 *S 的方法集都包含接受者为 T 或者 *T 的方法提升 这条规则说的是当我们嵌入一个类型的指针,嵌入类型的接受者为值类型或指针类型的方法将被提升,可以被外部类型的值或者指针调用。 上面是我golang中文网上找到的关于继承后方法集提升的说明,但是 package main import "fmt" type person struct { name string } func (p *person) ppointer(){ fmt.Println("this is person pointer func",p.name) } func(p person) pvalue(){ fmt.Println("this is person value func",p.name) } type student struct { person } type teacher struct { *person } func main() { svalue := student{person{"1111"}} svalue.ppointer() svalue.pvalue() //spointer := &student{person{"2222"}} //spointer.ppointer() //spointer.pvalue() // //tvalue := teacher{&person{"haha"}} //tvalue.ppointer() //tvalue.pvalue() // //tpointer := &teacher{&person{"啦啦"}} //tpointer.ppointer() //tpointer.pvalue() } 但是这个程序可以正常运行,外部类型值可以直接调用内部类型的接收者为指针的方法,和上面的第一条规则冲突。我的go版本是最新版本12,有没有帮忙大神指点一下迷津,谢谢了。 -----------------------------------分割线---------------------------------------------------- 非常感谢各位大佬指点迷津,综合大家的回答以及自己搜集的资料,大概理解了。 算是左右值问题。对于右值是无法取到变量地址的,所以编译器无法进行自动适配。而左值是可以自动适配的,所以值和指针可以互相调用对方方法。对于接口类型的调用,就需要遵循接口的方法集了。
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
lucima机器人#1 · 2019/5/21
兄弟你可能迷路了
justlikeu机器人#2 · 2019/5/21
哈哈,我每个语言讨论区都发了。渴望大佬指点迷津 【 在 lucima 的大作中提到: 】 : 兄弟你可能迷路了
talkischeap机器人#3 · 2019/5/21
我觉得go写起来真的很不舒服 。Java大法好。而且go的继承就是个笑话
skyblueice机器人#4 · 2019/5/21
我猜是 person的两个方法没有涉及到修改成员变量。你试试将其中一个方法改变name。这样只能是指针类型的方法集能用了吧 瞎猜的
tyang机器人#5 · 2019/5/21
https://goplay.space/#zNX7Cg4VlwO 这是测试结果和你说的第一条结论有冲突?
tyang机器人#6 · 2019/5/21
【 在 talkischeap 的大作中提到: 】 : 我觉得go写起来真的很不舒服 。Java大法好。而且go的继承就是个笑话 是因为你还没有用习惯? go中强调组合优于继承。 java中也提到这个概念? 继承是实现代码复用的有力手段,但它并非永远是完成这项工作的的最佳工具。--《Effective Java 中文版第2版》书中第16条。 参考文章:https://juejin.im/post/5becce876fb9a049d2359d01
wsx66848机器人#7 · 2019/5/21
兄弟,你可以试试person和*person是不是都可以调用pvalue 我记得接受者为T的方法 T和*T都可以调用
jxsrlsl1234机器人#8 · 2019/5/22
从java转到写go,但个人觉得还是java的对象思想比较易于理解,go貌似不叫继承吧,go基本上都是组合 【 在 wsx66848 (北邮新生) 的大作中提到: 】 : 兄弟,你可以试试person和*person是不是都可以调用pvalue 我记得接受者为T的方法 T和*T都可以调用
wsx66848机器人#9 · 2019/5/22
查了一下 左右值的问题 左值可以自动适配 值和指针可以互相调用对方的方法