Heim > Backend-Entwicklung > Golang > Wie erreicht man eine tiefe Kopie der Schnittstellenwerte in Go?

Wie erreicht man eine tiefe Kopie der Schnittstellenwerte in Go?

Mary-Kate Olsen
Freigeben: 2024-12-07 20:57:12
Original
742 Leute haben es durchsucht

How to Achieve a Deep Copy of Interface Values in Go?

Tiefe Kopie von Schnittstellenwerten in Go

Das direkte Kopieren eines Schnittstellenwerts in Go führt zu einer flachen Kopie, d. h. Änderungen an den kopierten Werten Der Wert wirkt sich auch auf das Original aus. Dies liegt daran, dass Schnittstellen einen Verweis auf den zugrunde liegenden konkreten Typ enthalten.

Ursache der Namensänderung

Um das Problem im bereitgestellten Code zu verstehen, analysieren wir, wie Schnittstellenwerte funktionieren . Die Benutzeroberfläche stellt einen Vertrag dar, und sowohl der Administrator als auch der Benutzer implementieren diesen Vertrag. Wenn wir Benutzer1 Benutzer2 zuweisen, erstellen wir im Wesentlichen einen Verweis auf dieselbe Admin-Instanz. Durch Ändern der Name()-Methode von Benutzer2 wird direkt die gemeinsam genutzte Admin-Instanz geändert, wodurch sich folglich auch der Name von Benutzer1 ändert.

Lösung mit Reflection

Um eine tiefe Kopie zu erreichen, benötigen wir um eine neue Instanz des zugrunde liegenden konkreten Typs zu erstellen und sie in einen neuen Benutzeroberflächenwert einzuschließen. Eine Möglichkeit hierfür ist die Reflexion. Wir können die Funktionen „reflect.ValueOf()“ und „reflect.Elem()“ verwenden, um den zugrunde liegenden Wert abzurufen, der in Benutzer1 gespeichert ist. Anschließend können wir „reflect.New()“ verwenden, um eine neue Instanz desselben Typs zu erstellen, und „reflect.MethodByName()“ verwenden, um die Methode „Name()“ abzurufen. Schließlich können wir die SetName()-Methode für die neue Instanz aufrufen und sie in einen neuen Benutzeroberflächenwert einschließen.

func CloneUser(user User) User {
    val := reflect.ValueOf(user)
    if val.Kind() != reflect.Ptr {
        panic("expected pointer")
    }
    elem := val.Elem()
    t := elem.Type()
    newElem := reflect.New(t).Elem()
    newElem.MethodByName("SetName").Call([]reflect.Value{reflect.ValueOf(newElem.String())})
    return newElem.Interface().(User)
}
Nach dem Login kopieren

Mit dieser Funktion können wir eine Kopie erstellen, die keine Auswirkungen auf das Original hat:

var user2 User = CloneUser(user1)
user2.SetName("user2")
fmt.Println(user1.Name(), user2.Name()) // Outputs: user1 user2
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWie erreicht man eine tiefe Kopie der Schnittstellenwerte in Go?. 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