为何Go编译器不认为Bar实现了I_Venus2和I_Mars2接口?
场景
Bar拥有签名返回*Foo的Get()方法Foo实现了I_Venus1和I_Mars1两个接口I_Venus2拥有签名返回I_Venus1的Get()方法I_Mars2拥有签名返回I_Mars1的Get()方法
type Foo struct { } type Bar struct { } func (*Bar) Get() *Foo { return nil } type I_Venus1 interface { } type I_Venus2 interface { Get() I_Venus1 } type I_Mars1 interface { } type I_Mars2 interface { Get() I_Mars1 } var _ I_Venus1 = &(Foo{}) // Foo满足I_Venus1接口 var _ I_Mars1 = &(Foo{}) // Foo满足I_Mars1接口
问题
var _ I_Venus2 = &(Bar{}) // *Bar未实现I_Venus2(Get方法类型错误) var _ I_Mars2 = &(Bar{}) // *Bar未实现I_Mars2(Get方法类型错误)
为什么Go编译器不认为Bar实现了I_Venus2和I_Mars2接口?
原因解析
Go语言对接口方法的匹配要求严格的类型一致性,哪怕返回的具体类型实现了接口要求的返回接口类型,也不能直接满足接口的方法签名要求。
具体来说:
I_Venus2要求实现的Get()方法必须返回I_Venus1类型,但Bar的Get()返回的是*Foo——这两个类型在方法签名层面是完全不同的,Go不会自动将*Foo隐式转换为I_Venus1来适配接口。- 同理,
I_Mars2要求Get()返回I_Mars1,而Bar的Get()返回*Foo,同样不满足签名匹配要求。
如果要让Bar实现I_Venus2,需要修改Bar的Get()方法返回类型为I_Venus1:
func (*Bar) Get() I_Venus1 { return &Foo{} }
修改后,*Bar就能满足I_Venus2的接口要求,同理I_Mars2也需要做类似修改。
内容的提问来源于stack exchange,提问作者thomas
相关产品推荐
相关产品推荐

