2017-10-25 20 views
0

リフレクションのみを使用してスライスに追加したいと思います。しかし、私はaの値を新しいスライスに "置き換える"方法を理解することはできません。リフレクションを使用してスライスに追加する

func main() { 
    fmt.Println("Hello, playground") 

    a := []string {"a","b","c"} 

    values := []string {"d","e"} 

    v := reflect.ValueOf(a) 

    fmt.Printf("%t\n\n", v.Type()) 
    fmt.Printf("%t\n\n", v.Type().Elem().Kind()) 

    for _, val := range values { 
     v.Set(reflect.Append(v, reflect.ValueOf(val))) 
    } 

    fmt.Printf("%t - %v", a, a) 
} 

このコードは、https://play.golang.org/p/cDlyH3jBDSで手を加えて利用できます。

答えて

1

reflect.Valueにラップされた値は、ポインタでない場合は変更できません。許可されている場合は、コピーを変更するだけで、混乱を招く可能性があります。スライス値は、バッキングアレイへのポインタ、長さ、および容量を含むヘッダです。 areflect.ValueOf()に渡すと、このヘッダーのコピーが作成され、渡されます。そのヘッダーコピーのみを変更できます。元のスライスのヘッダーでは要素の追加(したがってその長さとポインタと容量の変更)は行われず、元の配列は同じ配列を指していて、同じ長さと容量の値を保持します。詳細はAre Golang function parameter passed as copy-on-write?を参照してください。およびGolang passing arrays to the function and modifying it

ポインタから開始する必要があります。Value.Elem()を使用すると、参照先の値のreflect.Value記述子を取得できます。しかし、ポインタから始める必要があります。

fmt.Printf("%T\n\n", v.Type()) 
fmt.Printf("%T\n\n", v.Type().Elem().Kind()) 

// ... 

fmt.Printf("%T - %v", a, a) 
%T動詞( %tbool値のためである)を使用し、値の種類を印刷する

v := reflect.ValueOf(&a).Elem() 

も:あなたのコード内でこの一行を変更する

はそれを仕事になります

出力(Go Playgroundで試してください):

Hello, playground 
*reflect.rtype 

reflect.Kind 

[]string - [a b c d e] 
ゴーの反射をより深く理解するために

、ブログの記事をお読みください。The Laws of Reflection

および関連の質問+回答をお読みください。

Assigning a value to struct member through reflection in Go

Changing pointer type and value under interface with reflection

Using reflection SetString

+0

それは正しいだろうが私が 'reflect.ValueOf'に参照を渡さなかったので、' reflect。* 'を使って実行したすべての操作がコピーに適用され、したがって元の 'a'を変更する方法はありませんでしたか? – cimnine

+1

@cimnineはい、そうです。編集済みの回答を参照してください。 – icza

関連する問題