首页 > 后端开发 > Golang > 如何可靠地检测 Go 结构中的嵌入式接口是否具有使用反射的函数实现?

如何可靠地检测 Go 结构中的嵌入式接口是否具有使用反射的函数实现?

Mary-Kate Olsen
发布: 2024-12-22 19:35:11
原创
348 人浏览过

How Can I Reliably Detect If an Embedded Interface in a Go Struct Has a Function Implementation Using Reflection?

在结构体中使用嵌入式接口进行 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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板