从接口获取所有字段 [英] Get all fields from an interface

查看:40
本文介绍了从接口获取所有字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何知道我可以从 reply 对象/接口访问的字段?我试过反射,但似乎你必须先知道字段名称.如果我需要知道所有可用的字段怎么办?

How do I know the fields I can access from the reply object/interface? I tried reflection but it seems you have to know the field name first. What if I need to know all the fields available to me?

// Do sends a command to the server and returns the received reply.
Do(commandName string, args ...interface{}) (reply interface{}, err error)

推荐答案

您可以使用 reflect.TypeOf() 函数获取reflect.Type 类型描述符.从那里,您可以列出存储在界面中的动态值的字段.

You can use the reflect.TypeOf() function to obtain a reflect.Type type descriptor. From there, you can list fields of the dynamic value stored in the interface.

示例:

type Point struct {
    X int
    Y int
}

var reply interface{} = Point{1, 2}
t := reflect.TypeOf(reply)
for i := 0; i < t.NumField(); i++ {
    fmt.Printf("%+v
", t.Field(i))
}

输出:

{Name:X PkgPath: Type:int Tag: Offset:0 Index:[0] Anonymous:false}
{Name:Y PkgPath: Type:int Tag: Offset:4 Index:[1] Anonymous:false}

Type.Field() 调用的结果是一个 reflect.StructField 值,它是一个 struct,其中包含字段的名称等:

The result of a Type.Field() call is a reflect.StructField value which is a struct, containing the name of the field among other things:

type StructField struct {
    // Name is the field name.
    Name string
    // ...
}

如果你还想要字段的值,你可以使用 reflect.ValueOf() 获取reflect.Value(),然后你可以使用 Value.Field()Value.FieldByName():

If you also want the values of the fields, you may use reflect.ValueOf() to obtain a reflect.Value(), and then you may use Value.Field() or Value.FieldByName():

v := reflect.ValueOf(reply)
for i := 0; i < v.NumField(); i++ {
    fmt.Println(v.Field(i))
}

输出:

1
2

Go Playground 上试试.

注意:通常指向结构的指针包含在接口中.在这种情况下,您可以使用 Type.Elem()Value.Elem() 以导航"到指向的类型或值:

Note: often a pointer to struct is wrapped in an interface. In such cases you may use Type.Elem() and Value.Elem() to "navigate" to the pointed type or value:

t := reflect.TypeOf(reply).Elem()

v := reflect.ValueOf(reply).Elem()

如果不知道是不是指针,可以用Type.Kind()Value.Kind(),将结果与reflect.Ptr进行比较:

If you don't know whether it's a pointer or not, you can check it with Type.Kind() and Value.Kind(), comparing the result with reflect.Ptr:

t := reflect.TypeOf(reply)
if t.Kind() == reflect.Ptr {
    t = t.Elem()
}

// ...

v := reflect.ValueOf(reply)
if v.Kind() == reflect.Ptr {
    v = v.Elem()
}

Go Playground 上试试这个变体.

Try this variant on the Go Playground.

有关 Go 反射的详细介绍,请阅读博客文章:反射定律.

For a detailed introduction to Go's reflection, read the blog post: The Laws of Reflection.

这篇关于从接口获取所有字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆