ホームページ > バックエンド開発 > Golang > Reflection の「Append」関数が元の Go スライスを更新しないのはなぜですか?

Reflection の「Append」関数が元の Go スライスを更新しないのはなぜですか?

Barbara Streisand
リリース: 2024-11-26 01:10:12
オリジナル
624 人が閲覧しました

Why Doesn't Reflection's `Append` Function Update the Original Go Slice?

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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート