Heim > Backend-Entwicklung > Golang > Warum ändert „reflect.Append' von Reflection das ursprüngliche Go-Slice nicht?

Warum ändert „reflect.Append' von Reflection das ursprüngliche Go-Slice nicht?

Linda Hamilton
Freigeben: 2024-11-26 06:11:25
Original
658 Leute haben es durchsucht

Why Doesn't Reflection's `reflect.Append` Modify the Original Go Slice?

Mit Reflection an ein Go-Slice anhängen: Das verborgene Problem aufdecken

Beim Anhängen neuer Elemente an ein Slice mithilfe des Reflection-Pakets von Go kommt es zu einem unerwarteten Verhalten kann auftreten, wenn das Original-Slice unberührt bleibt. Dies wird im folgenden Codeausschnitt deutlich:

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
}
Nach dem Login kopieren

Obwohl ein Element an den Slice-Wert angehängt wird, behält das ursprüngliche Slice seine ursprüngliche Länge von Null. Diese rätselhafte Diskrepanz bedarf einer Erklärung.

Reflection- und Slice-Operationen

Reflection ermöglicht es uns, Datenstrukturen, einschließlich Slices, zur Laufzeit zu untersuchen und zu manipulieren. Die Funktion „reflect.Append“ nimmt, ähnlich wie „append“, einen Slice-Wert und ein neues Element und gibt einen neuen Slice-Wert zurück, der die aktualisierten Elemente enthält. Dieser Vorgang ändert jedoch nicht die ursprüngliche Slice-Referenz.

Im bereitgestellten Code weist die Anweisung „reflect.Append“ der Wertvariablen einen neuen „reflect.Value“ zu und ersetzt so effektiv die ursprüngliche Referenz auf das Slice. Während der Wert selbst aktualisiert wird, bleibt der ursprüngliche arr-Zeiger unverändert, daher die unveränderte Länge des arr-Slices in der Hauptfunktion.

Aktualisieren des ursprünglichen Slice

Zu Um das Original-Slice zu aktualisieren, müssen wir die Value.Set-Methode verwenden. Diese Methode ersetzt den Wert am angegebenen Index im Sliced-Wert durch einen neuen Wert. In unserem Fall müssen wir das gesamte Slice durch den neuen Wert ersetzen, der von Reflect zurückgegeben wird. Anhängen:

func appendToSlice(arrPtr interface{}) {
    valuePtr := reflect.ValueOf(arrPtr)
    value := valuePtr.Elem()

    value.Set(reflect.Append(value, reflect.ValueOf(55)))

    fmt.Println(value.Len()) // prints 1
}
Nach dem Login kopieren

Mit dieser Änderung wird das ursprüngliche Slice nun so aktualisiert, wie es in der Ausgabe widergespiegelt wird.

Fazit

Das Anhängen an ein Slice mittels Reflektion erfordert etwas mehr Nuancen als der herkömmliche Anhängevorgang. Die wichtigste Erkenntnis ist, dass Reflexionsoperationen mit Kopien von Werten funktionieren und dass man den ursprünglichen Wert explizit mit der Value.Set-Methode festlegen muss, um ihn zu aktualisieren.

Das obige ist der detaillierte Inhalt vonWarum ändert „reflect.Append' von Reflection das ursprüngliche Go-Slice nicht?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage