Go リフレクションの追加関数
Go では、リフレクションを使用して要素をスライスに追加しても、元のスライスが更新されないようです。これを次のコードで示します。
func appendToSlice(arrPtr interface{}) { valuePtr := reflect.ValueOf(arrPtr) value := valuePtr.Elem() value = reflect.Append(value, reflect.ValueOf(55)) fmt.Println(value.Len()) // prints 1 } func main() { arr := []int{} appendToSlice(&arr) fmt.Println(len(arr)) // prints 0 }
なぜ機能しないのですか?
根本原因は、reflect.Append の動作にあります。従来の追加関数と同様に、新しいスライス値を返します。この場合、value 変数に割り当てられた値がこの新しいスライスに置き換えられ、実質的にコピーが作成されます。
説明するために、何が起こっているかを強調表示するように例を変更してみましょう。
func appendToSlice(arrPtr *[]int) { value := *arrPtr value = append(value, 55) fmt.Println(len(value)) } func main() { arr := []int{} appendToSlice(&arr) fmt.Println(len(arr)) }
この変更されたコードは、使用していないにもかかわらず、同じ出力を生成します。リフレクション。
解決策
リフレクションを使用してスライスに正しく追加するには、Value.Set メソッドを使用して元の値を変更する必要があります。
func appendToSlice(arrPtr interface{}) { valuePtr := reflect.ValueOf(arrPtr) value := valuePtr.Elem() value.Set(reflect.Append(value, reflect.ValueOf(55))) fmt.Println(value.Len()) }
このアプローチでは、新しく作成されたスライスを value.Set に渡し、元のスライスを更新します。
以上がReflection の「Append」関数が元の Go スライスを更新しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。