Go语言:结构体匿名组合编译报错“ambiguous selector”

示例:

package main

import "fmt"

type T1 struct {
        id int
}

func (t T1) m1() {
        fmt.Println("T1.m1")
}

type T2 struct {
        id int
}

func (t T2) m1() {
        fmt.Println("T2.m1")
}

type MyStruct struct {
        T1
        T2
}

func main() {
        my := MyStruct{T1{449},T2{554}}
        my.m1()
        fmt.Printf("%d\n", my.id)
}

输出:

./t.go:28:4: ambiguous selector my.m1
./t.go:29:23: ambiguous selector my.id

 Go没有类似Java那样的继承,只能通过结构体的匿名组合来实现继承的特性。这个过程是在编译期完成的,例如上面的示例,假如没有T2的话,那么编译器会给MyStruct创建一个m1方法,然后在方法里调用T1.m1()。

func (m *MyStruct) m1(){
    m.T1.m1()
}

但是如果MyStruct又匿名组合了T2,而T2也有m1()方法,则编译器就不知道在给MyStruct创建m1方法时应该选择T1还是T2的m1(), 于是就报错“ambiguous selector”。除了方法以外,结构体的字段也有这种问题,如果没有T2,则编译器会把my.id替换为m.T1.id,如果取值可以确定的情况下,会进一步替换成其取值。而有了T2之后,编译器就不知道该把my.id替换成谁的取值。

因此,需要明确指明调用哪个结构体的m1()方法,读取哪个结构体的id,如下所示: 

func main() {
        my := MyStruct{T1{449},T2{554}}
        my.T1.m1()
        fmt.Printf("%d\n", my.T1.id)
}

相关文章:

《Go面试:Go通过匿名组合实现的继承和Java的继承之间的差别》

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值