Deep Copy in Golang: Techniken und Best Practices
James Reed
Infrastructure Engineer · Leapcell

Key Takeaways
- Deep Copy in Go ist essentiell, um unbeabsichtigte Änderungen an gemeinsam genutzten Daten zu vermeiden.
- Slices, Maps und Structs mit Referenztypen erfordern explizites Deep Copying.
- Bibliotheken von Drittanbietern wie
copier
können Deep-Copy-Operationen vereinfachen.
In der Softwareentwicklung ist das Erstellen von Kopien von Datenstrukturen eine häufige Anforderung. In Go (Golang) ist das Verständnis, wie man Deep Copies durchführt, unerlässlich, um sicherzustellen, dass Änderungen an einer Datenstruktur keine unbeabsichtigten Auswirkungen auf eine andere haben. Dieser Artikel untersucht verschiedene Methoden, um Deep Copying in Go zu erreichen.
Shallow Copy vs. Deep Copy verstehen
Bevor wir uns mit Deep-Copy-Techniken befassen, ist es entscheidend, zwischen Shallow und Deep Copies zu unterscheiden:
-
Shallow Copy: Erstellt eine neue Variable, die auf dieselben zugrunde liegenden Daten wie das Original verweist. Änderungen an den Daten wirken sich sowohl auf das Original als auch auf die Kopie aus.
-
Deep Copy: Erzeugt eine neue Variable mit einer eigenen separaten Kopie der Daten. Änderungen an den Daten in der Kopie haben keine Auswirkungen auf das Original.
Deep Copying von primitiven Typen
Primitive Typen in Go, wie z. B. Integer, Floats, Booleans und Strings, werden nach Wert kopiert. Das Zuweisen einer Variablen zu einer anderen erstellt eine Deep Copy:
a := 42 b := a b = 100 // 'a' bleibt 42, 'b' ist 100
In diesem Beispiel sind a
und b
unabhängig; das Ändern von b
hat keine Auswirkungen auf a
.
Deep Copying von zusammengesetzten Typen
Für zusammengesetzte Typen wie Arrays, Slices, Maps und Structs erfordert Deep Copying mehr Aufmerksamkeit.
Arrays
Arrays sind Werttypen in Go. Das Zuweisen eines Arrays zu einem anderen führt zu einer Deep Copy:
arr1 := [3]int{1, 2, 3} arr2 := arr1 arr2[0] = 10 // 'arr1' bleibt [1, 2, 3], 'arr2' ist [10, 2, 3]
Slices
Slices sind Referenztypen. Eine einfache Zuweisung kopiert den Slice-Header, nicht die zugrunde liegenden Daten:
slice1 := []int{1, 2, 3} slice2 := slice1 slice2[0] = 10 // Sowohl 'slice1' als auch 'slice2' sind [10, 2, 3]
Um eine Deep Copy eines Slices zu erstellen, müssen Sie die zugrunde liegenden Daten kopieren:
slice1 := []int{1, 2, 3} slice2 := make([]int, len(slice1)) copy(slice2, slice1) slice2[0] = 10 // 'slice1' ist [1, 2, 3], 'slice2' ist [10, 2, 3]
Maps
Maps sind ebenfalls Referenztypen. Eine direkte Zuweisung teilt dieselben zugrunde liegenden Daten:
map1 := map[string]int{"a": 1, "b": 2} map2 := map1 map2["a"] = 10 // Sowohl 'map1' als auch 'map2' sind {"a": 10, "b": 2}
So erstellen Sie eine Deep Copy einer Map:
map1 := map[string]int{"a": 1, "b": 2} map2 := make(map[string]int) for k, v := range map1 { map2[k] = v } map2["a"] = 10 // 'map1' ist {"a": 1, "b": 2}, 'map2' ist {"a": 10, "b": 2}
Structs
Structs sind Werttypen. Das Zuweisen eines Structs zu einem anderen kopiert die Daten:
type Point struct { X, Y int } p1 := Point{1, 2} p2 := p1 p2.X = 10 // 'p1' ist {1, 2}, 'p2' ist {10, 2}
Wenn ein Struct jedoch Referenztypen (z. B. Slices, Maps, Pointer) enthält, müssen Sie diese Felder manuell tief kopieren.
Verwenden von Bibliotheken von Drittanbietern
Für komplexe Datenstrukturen kann die manuelle Implementierung der Deep-Copy-Logik fehleranfällig sein. Bibliotheken von Drittanbietern wie copier können den Prozess vereinfachen:
import "github.com/jinzhu/copier" type Person struct { Name string Age int Friends []string } p1 := Person{Name: "Alice", Age: 30, Friends: []string{"Bob", "Charlie"}} var p2 Person copier.Copy(&p2, &p1) p2.Friends[0] = "David" // 'p1.Friends' ist ["Bob", "Charlie"], 'p2.Friends' ist ["David", "Charlie"]
Stellen Sie sicher, dass Sie verstehen, wie die Bibliothek Deep Copying durchführt, insbesondere für verschachtelte oder komplexe Typen.
Fazit
Deep Copying in Go erfordert eine sorgfältige Berücksichtigung der beteiligten Datentypen. Während primitive Typen unkompliziert sind, erfordern zusammengesetzte Typen eine explizite Behandlung, um echte Deep Copies zu gewährleisten. Die Verwendung von Bibliotheken von Drittanbietern kann bei der Verwaltung komplexer Strukturen hilfreich sein, aber überprüfen Sie immer, ob deren Verhalten mit den Anforderungen Ihrer Anwendung übereinstimmt.
FAQs
Slices und Maps sind Referenztypen, d. h. Zuweisungen kopieren nur Referenzen, nicht die zugrunde liegenden Daten.
Weisen Sie manuell einen neuen Slice zu und kopieren Sie jedes Element, um eine echte Deep Copy zu gewährleisten.
Beim Umgang mit komplexen, verschachtelten Strukturen, bei denen manuelles Deep Copying fehleranfällig ist.
Wir sind Leapcell, Ihre erste Wahl für das Hosten von Go-Projekten.
Leapcell ist die Serverless-Plattform der nächsten Generation für Webhosting, asynchrone Aufgaben und Redis:
Mehrsprachige Unterstützung
- Entwickeln Sie mit Node.js, Python, Go oder Rust.
Stellen Sie unbegrenzt Projekte kostenlos bereit
- Zahlen Sie nur für die Nutzung – keine Anfragen, keine Gebühren.
Unschlagbare Kosteneffizienz
- Pay-as-you-go ohne Leerlaufgebühren.
- Beispiel: 25 $ unterstützen 6,94 Millionen Anfragen bei einer durchschnittlichen Antwortzeit von 60 ms.
Optimierte Entwicklererfahrung
- Intuitive Benutzeroberfläche für mühelose Einrichtung.
- Vollautomatische CI/CD-Pipelines und GitOps-Integration.
- Echtzeitmetriken und -protokollierung für verwertbare Erkenntnisse.
Mühelose Skalierbarkeit und hohe Leistung
- Automatische Skalierung zur einfachen Bewältigung hoher Parallelität.
- Kein operativer Aufwand – konzentrieren Sie sich einfach auf das Bauen.
Erfahren Sie mehr in der Dokumentation!
Folgen Sie uns auf X: @LeapcellHQ