Bad*_*Zen 5 reflection interface embedding go
我现在的情况与此线程中的问题相同: 具有嵌入式匿名接口的结构的含义?
type A interface {
Foo() string
}
type B struct {
A
bar string
}
Run Code Online (Sandbox Code Playgroud)
习惯上,来自OOP语言的背景,看起来这种模式对我来说"试图说"是B必须实现接口A.但我现在已经知道"Go是不同的".所以,不是我最初预期的编译时检查,而是很高兴编译有或没有
func (B) Foo() string { .... }
Run Code Online (Sandbox Code Playgroud)
当下.正如上面的问题所指出的那样("释义"):"当你只想实现/部分/接口时,在结构中使用嵌入式接口非常有用".
据推测,这是因为此嵌入所发生的事情与其他情况一样 - 类型B的值将具有类型A的匿名接口值,作为字段.就个人而言,当我发现正交性安慰时,我也发现令人困惑的是反射包然后让我直接从B的类型获得A的方法,而不是错误/ nil如果没有接收器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")
}
}
Run Code Online (Sandbox Code Playgroud)
当它运行时,它会引起可怕的恐慌
HAS IT: func
panic: runtime error: invalid memory address or nil pointer dereference
Run Code Online (Sandbox Code Playgroud)
... 或不 - 取决于编译器/运行时是否能够找到上述方法.那么: 在触发它之前如何检测到这种情况呢?
那就是 - 有什么关于bMeth值,我可以用来看到反射返回的返回方法和func值中没有"真正的"实现?更准确地说,"是指向匿名接口值的函数表中函数的指针是否为零",或者您从具有反射的接口拉出的方法究竟发生了什么?
在一个够程包裹了整个事情,并尝试运行下延迟功能/恐慌是没有答案-因为恐慌而牺牲的不仅/推迟,但因为一般威力的功能,如果它确实存在,有副作用我现在不想要......
我是否想要像镜像编译器类型检查的运行时实现?或者有更简单的方法吗?我错误地想到了这个吗?
你不需要反思我的想法
method_in_table := B.Foo
fmt.Printf("%T \n", method_in_table)
Run Code Online (Sandbox Code Playgroud)
会输出你
func(main.B) string
Run Code Online (Sandbox Code Playgroud)
接口类型 A 在预先声明的 nil 处初始化,没有动态类型
var a A
if a==nil{
fmt.Printf("It's nil")
}
a.Foo()
Run Code Online (Sandbox Code Playgroud)
会给你同样的错误。所以实际检查可以是
if b.A != nil { b.Foo()}
Run Code Online (Sandbox Code Playgroud)