ホームページ >バックエンド開発 >Golang >Reflection の「reflect.Append」が元の Go スライスを変更しないのはなぜですか?それを修正するにはどうすればよいですか?

Reflection の「reflect.Append」が元の Go スライスを変更しないのはなぜですか?それを修正するにはどうすればよいですか?

DDD
DDDオリジナル
2024-11-23 09:49:18970ブラウズ

Why Doesn't Reflection's `reflect.Append` Modify the Original Go Slice, and How Can I Fix It?

リフレクションを使用した Golang スライスへの追加: 包括的な探索

問題ステートメント:

リフレクションを使用して要素をスライスに追加しようとすると、元のスライスが残ります。変わらない。これは、以下のコードで示されています。

package main

import (
    "fmt"
    "reflect"
)

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 関数は、組み込みの append 関数と同様に動作し、新しいスライス値。提供された例では、コードは戻り値を appendToSlice 関数内の value 変数に代入し、以前のreflect.Value を効果的に置き換えます。ただし、元の引数は変更されません。

リフレクションを使用して追加するための正しいアプローチ:

リフレクションを使用して元のスライスに要素を追加するには、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 を使用すると、追加されたスライス値で value 変数が更新され、arrPtr 引数によって参照される元のスライスに反映されます。

結論:

リフレクションを使用して Go スライスに追加するには、Value.Set メソッドを使用して変更する必要があります。元のスライス。 Reflect.Append 関数は新しいスライス値を返します。この値は、Value.Set を使用して元のスライスに割り当てる必要があります。これにより、リフレクション スコープ内で行われた変更が元のスライスに確実に反映されます。

以上がReflection の「reflect.Append」が元の Go スライスを変更しないのはなぜですか?それを修正するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。