4

リフレクトドキュメントによると、マップの特定のキーに格納されているデータの値を表すreflect.Value.MapIndex()aを返す必要があります。reflect.Valueしたがって、私の理解では、次の2つの式は同一である必要があります。最初のケースでは、から結果を取得していMapIndex()ます。MapIndex()2番目の例では、基礎となるデータを取得し、それに対して実行することで結果を取得reflect.ValueOf()しています。

reflect.ValueOf(map).MapIndex("Key")
reflect.ValueOf(reflect.ValueOf(map).MapIndex("Key").Interface())

なぜ追加reflect.ValueOf()が必要なのですか?

サンプルコード:

package main

import "fmt"
import "reflect"

func main() {
    test := map[string]interface{}{"First": "firstValue"}
    Pass(test)
}

func Pass(d interface{}) {
    mydata := reflect.ValueOf(d).MapIndex(reflect.ValueOf("First"))
    fmt.Printf("Value: %+v \n", mydata.Interface())
    fmt.Printf("Kind: %+v \n", mydata.Kind())
    fmt.Printf("Kind2: %+v \n", reflect.ValueOf(mydata.Interface()).Kind())
}

プレイする:http://play.golang.org/p/TG4SzrtTf0

4

2 に答える 2

2

これについてしばらく考えた後、これは当たり前のカテゴリに分類されます。interfacesこれは、他のものを指す参照オブジェクトであるGoの性質と関係があります。map[string]interface{}各キーの位置の値が文字列ではなく、であることを意味するようにマップを明示的に宣言したので、を保持するinterface{}を受け取っても驚くことはありません。reflect.Valueinterface{}

追加reflect.ValueOf()で1層深く掘り下げて、の基礎となる値を取得しinterface{}ます。私は2つの例を作成しましたが、どちらもこの動作を確認していると思います。

map[string]Stringerカスタムインターフェイスの使用例:http: //play.golang.org/p/zXCn9Fce3Q

package main

import "fmt"
import "reflect"

type Test struct {
    Data string
}

func (t Test) GetData() string {
    return t.Data
}

type Stringer interface {
    GetData() string
}

func main() {
    test := map[string]Stringer{"First": Test{Data: "testing"}}
    Pass(test)
}

func Pass(d interface{}) {
    mydata := reflect.ValueOf(d).MapIndex(reflect.ValueOf("First"))
    fmt.Printf("Value: %+v \n", mydata.Interface())
    fmt.Printf("Kind: %+v \n", mydata.Kind())
    fmt.Printf("Kind2: %+v \n", reflect.ValueOf(mydata.Interface()).Kind())
}

戻り値

Value: {Data:testing} 
Kind: interface 
Kind2: struct

使用例:http map[string]string//play.golang.org/p/vXuPzmObgN

package main

import "fmt"
import "reflect"

func main() {
    test := map[string]string{"First": "firstValue"}
    Pass(test)
}

func Pass(d interface{}) {
    mydata := reflect.ValueOf(d).MapIndex(reflect.ValueOf("First"))
    fmt.Printf("Value: %+v \n", mydata.Interface())
    fmt.Printf("Kind: %+v \n", mydata.Kind())
    fmt.Printf("Kind2: %+v \n", reflect.ValueOf(mydata.Interface()).Kind())
}

戻り値

Value: firstValue 
Kind: string 
Kind2: string 
于 2013-01-04T04:32:52.667 に答える
1
func Pass(d interface{}) {
    mydata := reflect.ValueOf(d).MapIndex(reflect.ValueOf("First"))
    fmt.Printf("Value: %+v \n", mydata.Interface())
    fmt.Printf("Kind: %+v \n", mydata.Kind())

プログラムのこの時点では、mydataはインターフェースであるため、Kind()が呼び出されたときにGoがそのように報告するのは当然のことです。

    fmt.Printf("Kind2: %+v \n", reflect.ValueOf(mydata.Interface()).Kind())

これを分解します:

s := mydata.Interface()  // s is a string
v := reflect.ValueOf(s)  // v is a reflect.Value
k := v.Kind()            // k is a reflect.Kind "string"

マップに文字列ではなくインターフェースが含まれているという事実につまずいているのではないかと思います。

于 2013-01-04T04:46:00.613 に答える