我怎么知道我可以从reply对象/界面访问的字段?我尝试过反射,但看来您必须首先知道字段名称。如果我需要了解所有可用字段怎么办?
reply
// 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类型描述符。从那里,您可以列出存储在界面中的动态值的字段。
reflect.TypeOf()
reflect.Type
例:
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\n", 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包含字段名称以及其他内容:
Type.Field()
reflect.StructField
struct
type StructField struct { // Name is the field name. Name string // ... }
如果还需要这些字段的值,则可以使用reflect.ValueOf()获取reflect.Value(),然后可以使用Value.Field()或Value.FieldByName():
reflect.ValueOf()
reflect.Value()
Value.Field()
Value.FieldByName()
v := reflect.ValueOf(reply) for i := 0; i < v.NumField(); i++ { fmt.Println(v.Field(i)) }
1 2
在Go Playground上尝试一下。
注意:通常将指向struct的指针包装在接口中。在这种情况下,您可以使用Type.Elem()和Value.Elem()“导航”指向的类型或值:
Type.Elem()
Value.Elem()
t := reflect.TypeOf(reply).Elem() v := reflect.ValueOf(reply).Elem()
如果您不知道它是否是指针,则可以使用Type.Kind()和Value.Kind()进行检查,并将结果与reflect.Ptr:
Type.Kind()
Value.Kind()
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上尝试使用此变体。
有关Go的思考的详细介绍,请阅读博客文章:The Laws of Reflection。