Heim > Artikel > Backend-Entwicklung > So implementieren Sie Deep Copy in Golang
In der Go-Sprache (Golang) müssen wir oft Strukturen oder Objekte kopieren. Direkte Zuweisungen oder flaches Kopieren können zu Fehlern führen, die schwer zu debuggen sind. Daher ist eine tiefe Kopie unbedingt erforderlich. In diesem Artikel wird vorgestellt, wie Golang Deep Copy implementiert.
Das Konzept des Deep Copy
Deep Copy besteht darin, eine neue Kopie aller internen Attribute eines Objekts zu erstellen. Selbst wenn ein bestimmtes Attribut im Originalobjekt und in der Kopie geändert wird, wirkt es sich auf diese Weise nicht gegenseitig aus. Flaches Kopieren kopiert nur Zeiger und mehrere Objekte zeigen auf dieselbe Adresse. Das Ändern der Eigenschaften eines Objekts wirkt sich auf andere Objekte aus.
Deep-Copy-Methode in Golang
Methode 1: Verwenden Sie json.Marshal() und json.Unmarshal()
Diese Methode ist relativ einfach, Sie können json.Marshal() und json.Unmarshal() in der Standardbibliothek verwenden Funktion.
Zum Beispiel:
type Person struct { Name string Age int } person1 := &Person{"Lucas", 18} var person2 Person temp, _ := json.Marshal(person1) //使用json.Marshal()将person1转换成json格式 json.Unmarshal(temp, &person2) //使用json.Unmarshal()将json格式转换成person2实例
Allerdings hat diese Methode einige Nachteile. Zunächst müssen Sie sicherstellen, dass das konvertierte JSON-Format nicht denselben JSON wie das Feld hat, da der JSON sonst nicht wieder in die Struktur konvertiert werden kann. Zweitens müssen sowohl json.Marshal() als auch json.Unmarshal() das gesamte Objekt durchlaufen, was zu einer langsameren Geschwindigkeit führt. Daher kann es nicht für komplexe Datenstrukturen und Anwendungen verwendet werden, die eine effiziente Leistung erfordern.
Methode 2: Verwenden Sie die rekursive Methode
Rekursives Deep Copy ist die am häufigsten verwendete Methode. Durchlaufen Sie jedes Element im Objekt oder Array, kopieren Sie es direkt, wenn es sich um einen Basistyp handelt, oder rufen Sie die Deep-Copy-Funktion rekursiv auf, wenn es sich um einen komplexen Typ handelt. Der Code lautet wie folgt:
func DeepCopy(input interface{}) interface{} { if input == nil { return nil } switch reflect.TypeOf(input).Kind() { case reflect.Bool, reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64: return input case reflect.Struct: in := reflect.ValueOf(input) out := reflect.New(in.Type()).Elem() for i := 0; i < in.NumField(); i++ { out.Field(i).Set(DeepCopy(in.Field(i).Interface())) } return out.Interface() case reflect.Array, reflect.Slice: in := reflect.ValueOf(input) out := reflect.MakeSlice(in.Type(), in.Len(), in.Cap()) for i := 0; i < in.Len(); i++ { out.Index(i).Set(DeepCopy(in.Index(i).Interface())) } return out.Interface() case reflect.Map: in := reflect.ValueOf(input) out := reflect.MakeMapWithSize(in.Type(), in.Len()) for _, key := range in.MapKeys() { out.SetMapIndex(DeepCopy(key.Interface()).(reflect.Value), DeepCopy(in.MapIndex(key).Interface()).(reflect.Value)) } return out.Interface() default: panic(fmt.Sprintf("Unable to deepcopy object of type %v", reflect.TypeOf(input))) } }
In diesem Code verwenden wir zunächst Reflect.TypeOf(), um den Objekttyp abzurufen, und rufen dann basierend auf der Typdefinition verschiedene Deep-Copy-Funktionen auf.
Wir können gängige Typen testen:
type Person struct { Name string Age int } type Object struct { Num int Str string Slice []int Map map[string]int Person Person } func main() { obj1 := &Object{1, "hello", []int{2, 3}, map[string]int{"age": 18}, Person{"Lucas", 20}} //深拷贝 obj2 := DeepCopy(obj1) //修改obj1的Name字段 obj1.Person.Name = "Nina" fmt.Println("obj1:", obj1) fmt.Println("obj2:", obj2) }
Die Ausgabeergebnisse lauten wie folgt:
obj1: &{1 hello [2 3] map[age:18] {Nina 20}} obj2: &{1 hello [2 3] map[age:18] {Lucas 20}}
Es ist ersichtlich, dass die Werte von obj1 und obj2 unterschiedlich sind und eine Änderung des Werts von obj1 keine Auswirkungen auf obj2 hat.
Zusammenfassung
In diesem Artikel werden zwei Methoden zum Deep Copying in Golang vorgestellt. Für einfache Strukturen können Sie json.Marshal() und json.Unmarshal() verwenden. Bei komplexen Datenstrukturen können rekursive Methoden zum Deep Copying eingesetzt werden. Bei der Durchführung einer Tiefenkopie müssen Sie auf die Beurteilung des Datentyps achten, um unnötige Fehler zu vermeiden.
Das obige ist der detaillierte Inhalt vonSo implementieren Sie Deep Copy in Golang. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!