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
_ 型記述子を取得できます。そこから、インターフェースに格納された動的な値のフィールドをリストできます。
例:
_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 StructField struct {
// Name is the field name.
Name string
// ...
}
_
フィールドの値も必要な場合は、 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 で試してください。
注:多くの場合、構造体へのポインタはインターフェイスでラップされます。このような場合、Type.Elem()
および Value.Elem()
を使用して、ポイントされた型または値に「ナビゲート」できます。
_t := reflect.TypeOf(reply).Elem()
v := reflect.ValueOf(reply).Elem()
_
ポインタかどうかわからない場合は、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 を参照してください。