In Go spielen die eingebauten Funktionen append, len und cap eine Schlüsselrolle bei der Arbeit mit Slices.
Beispiel:
arr := []int{1,2,3} arr2 := append(arr, 4) // arr2 kann im selben oder in einem neuen backing array sein, abhängig von cap(arr)
Details:
Was passiert, wenn einem Slice ein Stück "abgeschnitten" und ein Element über append hinzugefügt wird? Wirkt sich das auf das ursprüngliche Array aus?
Antwort: Wenn cap es zulässt, wird append das Element "am Ende" des ursprünglichen Arrays speichern, und die Änderungen sind durch alle Slices sichtbar, die auf dasselbe Array verweisen.
Beispiel:
a := []int{1,2,3,4} b := a[:2] // [1 2], len=2, cap=4 b = append(b, 10) // a ändert sich: a -> [1, 2, 10, 4]
Geschichte
Im Team wurden Elemente zu einem untergeordneten Slice hinzugefügt, und unerwartet änderten sich die Daten im übergeordneten Array — dies führte zu einer Inkonsistenz in der Geschäftslogik und äußerst schwierigen Bugs beim Debuggen der Aufgabenverteilung zwischen Benutzern.
Geschichte
Bei einem erneuten Aufruf von append auf einem großen Slice wurde erwartet, dass das neue Array immer neu zugewiesen wird, aber in Wirklichkeit arbeiteten mehrere Teile des Systems weiterhin mit demselben "backing array", was eine race condition und Datenkorruption verursachte.
Geschichte
Ein Entwickler wies ein Slice fester Größe mit make zu, machte aber einen Fehler und tauschte die Argumente: make([]int, cap, len). Infolgedessen arbeitete die auf Kapazität ausgerichtete Logik unerwartet auf die Länge, was eine Panik beim Überschreiten von s[0:len] auslöste.