结构体类型,两种不同方式嵌套接口类型。
由于接口类型嵌套允许重名方法,I 接口有三个方法。SI 嵌套 I,SI 也有三个方法
结构体嵌套不允许重名,M 方法,被自动隐藏了?,SI12嵌套 I1, I2, SI12 只有两个方法
package main
import (
"fmt"
"reflect"
)
type I1 interface {
M()
M1()
}
type I2 interface {
M()
M2()
}
type I interface {
I1
I2
}
type SI struct {
I
}
type SI12 struct {
I1
I2
}
func main() {
var si SI
var si12 SI12
DumpMethodSet(si)
DumpMethodSet(si12)
}
func DumpMethodSet(i interface{}) {
dynTyp := reflect.TypeOf(i)
if dynTyp == nil {
fmt.Printf("there is no dynamic type\n")
return
}
n := dynTyp.NumMethod()
if n == 0 {
fmt.Printf("%s's method set is empty!\n", dynTyp)
return
}
fmt.Printf("%s's method set:\n", dynTyp)
for j := 0; j < n; j++ {
fmt.Println("-", dynTyp.Method(j).Name)
}
fmt.Printf("\n")
}
============
main.SI's method set:
- M
- M1
- M2
main.SI12's method set:
- M1
- M2
作者回复: 问题非常好!👍
我们知道:一个类型的方法集合中的方法都可以被这个类型实例所调用。反过来说,只有能被类型实例直接调用的方法才能进入其方法集合。
在你的例子中,SI12嵌入了I1和I2,这就造成了I1和I2的方法集合的交集M在SI12中存在了歧义。当使用SI12的实例调用M时,比如:
var s SI12
s.M() // go编译器会报错!不确定究竟是调用s.I1.M还是s.I2.M
于是M因这种未决的歧义性而不能被列入SI12的方法集合中。