登录
首页 >  Golang >  Go问答

如何在 Go 中正确检查接收器类型是否实现接口?

来源:stackoverflow

时间:2024-03-04 12:27:24 213浏览 收藏

在Golang实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《如何在 Go 中正确检查接收器类型是否实现接口?》,聊聊,希望可以帮助到正在努力赚钱的你。

问题内容

我正在尝试确定 struct 上的字段是否实现具有指针接收器的给定接口。

由于我的困惑,我有一个 go 演示设置。

假设我有以下 interface

type stringee interface {
    fromstring(s string) error
}

通过枚举实现它:

type enum int

const (
    enumunknown enum = iota
    enuma
    enumb
)

func (my *enum) string() string { return enumtostr[*my] }

func (my *enum) fromstring(s string) error {
    if v, ok := enumfromstr[s]; ok {
        *my = v
        return nil
    }
    return errors.new("invalid value")
}

var enumtostr = map[enum]string{
    enuma: "a",
    enumb: "b",
}
var enumfromstr = func() map[string]enum {
    m := make(map[string]enum)
    for k, v := range enumtostr {
        m[v] = k
    }
    return m
}()

我首先获取interfacetype

var stringeetype = reflect.typeof(new(stringee)).elem()

然后我可以对其进行检查:

e := enuma
e.fromstring("b")
e.string() // "b"


reflect.valueof(e).type().implements(stringeetype) // false
reflect.valueof(&e).type().implements(stringeetype) // true

这是可以预料的。但是,我不知道该怎么做,如果 type 是 struct 的字段,则将检查作为指针执行。例如:

假设我有以下 struct

type struct struct {
    e enum
}

如何检查 e 是否实现了 interface stringee

t := Struct{}
tv := reflect.ValueOf(&t)
fieldE := tv.Elem().Field(0)

fieldE.Type().Implements(stringeeType) // false

https://play.golang.org/p/eruq8ego2-e


解决方案


如果该字段是可寻址的,则获取该字段的地址并检查该值:

if fielde.cannaddr() { 
    impl := fielde.addr().type().implements(stringeetype)
    fmt.println("&t.e implements stringee", impl)
}

或者,如果您只有 reflect.type 而不是 relect.value,例如,在检查结构体的字段是否实现接口时,您可以使用 reflect.ptrto 来实现此目的。

此函数将检查给定结构的任何字段是否实现 stringee

func CheckFields(s interface{}) {
    rt := reflect.TypeOf(s)
    for i := 0; i < rt.NumField(); i++ {
        field := rt.Field(i)
        ptr := reflect.PtrTo(field.Type)
        if ptr.Implements(stringeeType) {
            fmt.Println(field.Name + " implements Stringee")
        }
    }
}

type Test struct {
    Field  int
    Field2 MyTypeWithStringee
}

test := Test{}

CheckFields(test)

以上就是《如何在 Go 中正确检查接收器类型是否实现接口?》的详细内容,更多关于的资料请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>