Heim >Backend-Entwicklung >Golang >Warum ändert Reflect.Append das ursprüngliche Go-Slice nicht und wie kann ich das Problem beheben?

Warum ändert Reflect.Append das ursprüngliche Go-Slice nicht und wie kann ich das Problem beheben?

DDD
DDDOriginal
2024-12-04 10:51:101012Durchsuche

Why Doesn't Reflect.Append Modify the Original Go Slice, and How Can I Fix It?

Anhängen an ein Go-Lang-Slice mithilfe von Reflexion: Die Mechanik verstehen

Beim Versuch, ein neues Element mithilfe von Reflexion an ein Slice anzuhängen, ist dies der Fall erwartet, dass das Original-Slice entsprechend aktualisiert wird. Es kann jedoch beobachtet werden, dass dies nicht der Fall ist, wie im folgenden Code gezeigt:

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
}

Den Grund verstehen

Der Schlüssel zum Verständnis dieses Verhaltens liegt darin beim Erkennen der Funktionsweise von Reflect.Append. Ähnlich wie die Append-Funktion in der Standardbibliothek erstellt Reflect.Append einen neuen Slice-Wert, anstatt den Originalwert zu ändern. Im obigen Codeausschnitt wird dem Wert das neu erstellte Segment zugewiesen, das den ursprünglichen Wert innerhalb der Funktion ersetzt, sich jedoch nicht auf das ursprüngliche Argument außerhalb der Funktion auswirkt.

Korrektur des Ansatzes

Um das Original-Slice mithilfe von Reflektion zu ändern, sollte die Value.Set-Methode verwendet werden. Diese Methode ermöglicht die Aktualisierung des ursprünglichen Werts. Die korrigierte Version der appendToSlice-Funktion wäre:

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

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

    fmt.Println(value.Len())
}

Dadurch wird sichergestellt, dass das ursprüngliche Slice wie erwartet geändert wird und die folgende Ausgabe erhalten wird:

1
1

Schlussfolgerung

Wenn Sie Reflektion zum Ändern von Slices verwenden, ist es wichtig zu berücksichtigen, dass „reflect.Append“ ein neues Slice erstellt, anstatt es zu ändern Original. Durch die Verwendung der Value.Set-Methode kann man den ursprünglichen Slice durch Reflexion effektiv modifizieren und so sicherstellen, dass das erwartete Ergebnis erreicht wird.

Das obige ist der detaillierte Inhalt vonWarum ändert Reflect.Append das ursprüngliche Go-Slice nicht und wie kann ich das Problem beheben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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