In Go sind die meisten eingebauten Datentypen (z. B. int, float, struct) — veränderlich, wenn sie als Variablen deklariert sind, da bei der Übergabe nach Wert die gesamte Struktur oder der Wert kopiert wird. Aber es gibt einen kleinen Unterschied: Slices (slice), Karten (map), Kanäle (channel) — sind Referenztypen mit ihrer eigenen internen Logik zur Datenspeicherung.
Basistypen:
x := 10 y := x // Hier wird eine Kopie des Wertes erstellt, x und y sind nicht miteinander verbunden y = 20 // x bleibt 10
Slices:
a := []int{1,2,3} b := a // Verweis auf denselben Basis-"Untergrund" des Arrays b[0] = 100 // jetzt ist auch a[0] == 100
Das ist wichtig, wenn eine Funktion oder Methode eine Struktur oder ein Slice entgegennimmt, denn Änderungen können entweder die ursprünglichen Daten betreffen oder nicht, je nach Datentyp und Art der Übergabe (nach Wert oder nach Referenz).
Frage: "Wenn Sie einem Slice ein anderes zuweisen, erhalten Sie dann eine tiefe Kopie oder zeigen beide auf dieselben Daten?"
Antwort: Bei einfacher Zuweisung von Slices (b := a) — zeigen beide auf dasselbe Basisarray, haben jedoch eine unabhängige Länge und Kapazität. Änderungen über eines der Slices im Array-Daten sind im anderen sichtbar.
Beispiel:
a := []int{1,2,3} b := a b[0] = 42 fmt.Println(a) // [42 2 3]
Um eine tiefe Kopie zu erstellen, verwendet man copy:
c := make([]int, len(a)) copy(c, a) c[0] = 99 fmt.Println(a) // [42 2 3], c — eine unabhängige Kopie
Geschichte
Der Datenfilterdienst begann, unerwartete Ergebnisse zurückzugeben: Ein Entwickler übergab Slices zwischen mehreren Funktionen, ohne sie zu kopieren, und änderte deren Zustand. Aufgrund der Änderungen an Slices an verschiedenen Stellen brach die Logik der Anwendung zusammen, es traten seltsame Bugs in den Daten auf, die lange nicht gefunden werden konnten.
Geschichte
Datenverlust nach der Übergabe einer Struktur: In einem Projekt wurde bei der Serialisierung von Daten versehentlich ein obligatorisches Feld aus der Struktur entfernt, weil das Objekt per Referenz übergeben wurde, anstatt eine Kopie davon zu erstellen. Infolgedessen ging aufgrund dessen kritische Informationen in der Produktion verloren.
Geschichte
Fehler bei der parallelen Arbeit mit maps: Ein Entwickler kopierte einen Verweis auf eine map und dachte, dass Änderungen keinen Einfluss auf das Original haben würden, wie es in anderen Sprachen der Fall ist. Infolgedessen trat ein Datenrennen auf, als in verschiedenen Goroutinen gearbeitet wurde, was zu Abstürzen der Anwendung führte.