type A interface {
Foo() string
}
type B struct {
A
bar string
}
习惯上,来自 OOP 语言的背景,这种模式对我来说“试图说”是 B 必须实现接口 A。但我现在明白“Go 是不同的”。因此,与我最初预期的编译时检查不同,这很高兴在有或没有
func (B) Foo() string { .... }
展示。正如上面的问题所指出的(释义):“在结构中使用嵌入式接口非常适合您只想实现接口的 /part/ ”。
据推测,这是因为这个嵌入发生的事情就像在其他所有情况下一样 - 类型 B 的值将具有类型 A 的匿名接口值作为字段。就我个人而言,虽然我发现正交性令人欣慰,但我也发现反射包会让我以这种方式直接从 B 的类型获取 A 的方法,如果不存在接收器 B 的方法,则不会出错/零。但是 - 这个问题不是关于背后的想法 - 它是关于在之后如何初始化接口值b := B{}:
func main() {
bType := reflect.TypeOf(B{})
bMeth, has := bType.MethodByName("Foo")
if has {
fmt.Printf("HAS IT: %s\n",bMeth.Type.Kind())
res := bMeth.Func.Call([]reflect.Value{reflect.ValueOf(B{})})
val := res[0].Interface()
fmt.Println(val)
} else {
fmt.Println("DOESNT HAS IT")
}
}
当它运行时,它会引起可怕的恐慌
HAS IT: func
panic: runtime error: invalid memory address or nil pointer dereference
...或不- 取决于编译器/运行时是否能够找到上述方法。那么: 如何在触发之前检测到这种情况?
也就是说 - 是否有关于 bMeth 值的一些信息,我可以使用它来查看反射返回的返回 Method 和 func 值中不存在“真实”实现?这是否更准确地说是“匿名接口值的函数表中函数的指针为零”,或者从没有实现的带有反射的接口中提取的方法究竟发生了什么?
将整个事情包装在一个 goroutine 中并尝试在 defer/panic 下运行该函数并不是答案——不仅是因为 panic/defer 的开销,而且因为该函数通常可能(如果它确实存在)有副作用我现在不想...
我是否想要一个类似于编译器类型检查的运行时实现?或者有更简单的方法吗?我是否错误地考虑了这一点?
呼如林
相关分类