Ce face append
append adaugă unul sau mai multe elemente la finalul unui slice și returnează slice-ul nou. Dacă slice-ul are capacitate liberă, elementele se scriu în același array; dacă nu, append alocă un array mai mare (de obicei dublu pentru slice-uri mici), copiază elementele vechi și le adaugă pe cele noi.
Pentru că array-ul se poate schimba, rezultatul trebuie salvat mereu: s = append(s, x). Un slice nil funcționează direct: var s []int; s = append(s, 1). Un alt slice se adaugă cu ...: append(a, b...). Caz special: la un []byte poți adăuga un text cu append(b, "text"...).
Dacă știi dinainte câte elemente vor fi, creează slice-ul cu make([]T, 0, n): append nu va mai realoca memorie.
Parametri
| Parametru | Descriere |
|---|---|
slice |
Slice-ul la care se adaugă (poate fi nil). |
elems |
Elementele de adăugat, de același tip; sau un alt slice urmat de .... |
Ce returnează
Slice-ul cu elementele adăugate. Poate folosi același array sau unul nou.
Exemple
Exemplul 1: Adăugare de elemente și de slice-uri
package main
import "fmt"
func main() {
var cumparaturi []string
cumparaturi = append(cumparaturi, "pâine")
cumparaturi = append(cumparaturi, "lapte", "ouă")
altele := []string{"mere", "brânză"}
cumparaturi = append(cumparaturi, altele...)
fmt.Println(cumparaturi, len(cumparaturi))
b := []byte("Bună")
b = append(b, ", Ana"...)
fmt.Println(string(b))
}
Rezultat
[pâine lapte ouă mere brânză] 5
Bună, Ana
Exemplul 2: Cum crește capacitatea
Capacitatea se mărește în salturi; valorile exacte depind de versiunea Go, dar sunt mereu aceleași pentru același program.
package main
import "fmt"
func main() {
var s []int
capAnterior := -1
for i := range 20 {
s = append(s, i)
if cap(s) != capAnterior {
fmt.Printf("len=%2d cap=%2d\n", len(s), cap(s))
capAnterior = cap(s)
}
}
rezervat := make([]int, 0, 20) // fără realocări
for i := range 20 {
rezervat = append(rezervat, i)
}
fmt.Println("cu make: len", len(rezervat), "cap", cap(rezervat))
}
Rezultat
len= 1 cap= 4
len= 5 cap= 8
len= 9 cap=16
len=17 cap=32
cu make: len 20 cap 20
Exemplul 3: Capcana: două slice-uri care împart același array
a are capacitate liberă, deci ambele append scriu în aceeași poziție. slices.Clone sau o capacitate limitată (a[:3:3]) evită asta.
package main
import "fmt"
func main() {
a := make([]int, 3, 10)
b := append(a, 100)
c := append(a, 200)
fmt.Println("b:", b, "c:", c) // b a fost suprascris!
d := append(a[:3:3], 100) // capacitate limitată: array nou
e := append(a[:3:3], 200)
fmt.Println("d:", d, "e:", e)
}
Rezultat
b: [0 0 0 200] c: [0 0 0 200]
d: [0 0 0 100] e: [0 0 0 200]
Greșeli frecvente
append(s, x)fără atribuire:append(s, x) (value of type []int) is not used.append(a, b)cubslice, fără...:cannot use b (variable of type []int) as int value in argument to append.- Salvarea rezultatului în alt slice decât cel original (
b := append(a, x)) și apoi folosirea ambelor: pot împărți memoria.
Comenzi înrudite
slice-uri: Lista dinamică din Go: o fereastră peste un array, cu lungime (len) și capacitate (cap), care crește cu append.make: Creează și inițializează slice-uri, map-uri și canale, cu lungime, capacitate sau buffer dat.copy: Copiază elemente dintr-un slice în altul, cât încape în cel mai scurt, și returnează câte a copiat.len și cap: len dă numărul de elemente (sau octeți la texte); cap dă capacitatea unui slice, array sau canal.funcții variadice (...): Funcții care primesc oricâte argumente de același tip prin …T; în funcție ele sunt un slice.