ProgrammierungGo Backend Entwickler

Beschreiben Sie die Besonderheiten des Kopierens von Slices und Strukturen in Go. Wie können unerwartete Effekte bei der Arbeit mit ihnen vermieden werden?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

Strukturen in Go werden nach Wert kopiert (tiefe Kopie der ersten Ebene, verschachtelte Strukturen werden nach derselben Regel kopiert), während Slices nach Wert kopiert werden, aber nur die Struktur und nicht das zugrunde liegende Datenarray kopiert wird: sowohl das Original als auch die Kopie des Slices verweisen auf dasselbe Backing-Array, daher wird eine Änderung über ein Slice auch im anderen reflektiert, es sei denn, es wird eine explizite Kopie des Arrays über copy() gemacht.

Beispiel für das Kopieren eines Slices:

s1 := []int{1,2,3} s2 := s1 // verweist auf dasselbe Puffer! s2[0] = 99 fmt.Println(s1) // [99 2 3] // Für eine Arraykopie: s3 := make([]int, len(s1)) copy(s3, s1) s3[0] = 42 fmt.Println(s1) // [99 2 3], s3 ist unabhängig

Beim Kopieren von Strukturen: wenn eine Struktur ein Zeigerfeld oder ein Slice-Feld enthält, werden nur die Verweise und nicht die Werte kopiert.

Fangfrage

Welcher Weg "kloniert" ein Slice so, dass seine Änderungen das Original nicht betreffen?

Potentiell falsche Antwort: Einfach b := a machen. Richtig:

  • Man muss copy verwenden, ein neues Slice der gewünschten Länge erstellen und die Daten kopieren:
newS := make([]int, len(a)) copy(newS, a)

Beispiele echter Fehler wegen fehlenden Wissens über die Feinheiten des Themas


Geschichte

Beschreibung: Bei der dynamischen Generierung von Datenbankanfragen wurden die Felder des Slices in der Anforderungsstruktur verändert, ohne Kopien zu erstellen. Bei wiederholten Anfragen überschritten sich die Daten, was zu inkorrekten Ergebnissen für die Benutzer führte.


Geschichte

Beschreibung: Bei der parallelen Datenverarbeitung wurde eine Kopie der Struktur durch Zuweisung erstellt und das Slice in einem Goroutine erweitert, während ein anderes Original-Slice parallel verwendet wurde. Die Daten "überschrieben" sich, was zu unvorhersehbaren Fehlern führte.


Geschichte

Beschreibung: Eine Pufferstruktur wurde verwendet, das gleichzeitige Kopieren durch Zuweisung berücksichtigte nicht die verschachtelten Slices (flache Kopie), Änderungen an einem Ort betrafen einen anderen Puffer — letztendlich war es schwierig, die Quelle der Datenänderung nachzuvollziehen.