在结构体中使用嵌入式接口进行 Go 反射
检测“真实”函数
Go 的反射包提供在运行时访问有关类型和值的信息。这可能是一个强大的工具,但在使用结构中的嵌入式接口时它也可能会令人困惑。
考虑以下示例:
type A interface { Foo() string } type B struct { A bar string }
正如您所观察到的,Go 不在编译时强制执行嵌入式接口。这意味着可以在不提供实现的情况下将接口嵌入到结构中。
使用反射访问方法
您可以使用反射包从struct 的嵌入接口,即使没有提供实现:
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") }
但是,如果嵌入接口没有提供
检测是否存在实现
要检测嵌入式接口是否没有实现,您可以检查指向该函数的指针匿名接口值的函数表:
b := B{} bType := reflect.TypeOf(b) bMeth, has := bType.MethodByName("Foo") if has { bMethPtr := bMeth.Func.Pointer() if bMethPtr == 0 { fmt.Println("No implementation") } else { fmt.Println("Implementation found") } } else { fmt.Println("Interface not embedded") }
如果函数指针为0,则没有实现。否则,存在实现。
替代方法
您还可以使用更简单的方法:
if b.A != nil { b.Foo() }
如果设置了嵌入式接口如果设为 nil,则 b.Foo() 调用将会出现恐慌。否则,它将执行实现(如果有)。
以上是如何可靠地检测 Go 结构中的嵌入式接口是否具有使用反射的函数实现?的详细内容。更多信息请关注PHP中文网其他相关文章!