Ce face slice-uri
Un slice ([]T) este felul obișnuit de a ține o listă de valori în Go. Intern, el are trei părți: un pointer spre un array, o lungime (len, câte elemente vezi) și o capacitate (cap, cât loc există până la capătul array-ului). Se creează cu un literal ([]string{"a", "b"}), cu make([]int, n) sau din alt slice ori array (s[1:3]).
append adaugă elemente și returnează slice-ul rezultat: s = append(s, x). Când capacitatea nu ajunge, append alocă un array nou, mai mare, și copiază elementele. De aceea rezultatul lui append trebuie mereu salvat.
Expresia s[i:j] creează un slice nou care împarte același array: modificarea unui element prin el se vede și în s. Pentru o copie independentă folosește slices.Clone(s) sau copy. Pachetul slices are funcții pentru sortare, căutare, inserare și ștergere.
Exemple
Exemplul 1: Creare, append, len și cap
Capacitatea crește automat când append nu mai are loc.
package main
import "fmt"
func main() {
var cos []string
fmt.Println(cos, len(cos), cap(cos), cos == nil)
cos = append(cos, "pâine")
cos = append(cos, "lapte", "ouă")
fmt.Println(cos, len(cos), cap(cos))
note := make([]int, 3, 10)
note[0], note[1], note[2] = 9, 7, 10
fmt.Println(note, len(note), cap(note))
}
Rezultat
[] 0 0 true
[pâine lapte ouă] 3 3
[9 7 10] 3 10
Exemplul 2: Sub-slice-urile împart memoria
primele este o fereastră peste orase; slices.Clone face o copie separată.
package main
import (
"fmt"
"slices"
)
func main() {
orase := []string{"Iași", "Cluj", "Arad", "Sibiu", "Brașov"}
primele := orase[:2]
mijloc := orase[1:4]
fmt.Println(primele, mijloc, orase[3:])
primele[1] = "CLUJ"
fmt.Println("după modificare:", orase)
copie := slices.Clone(orase)
copie[0] = "Galați"
fmt.Println("original:", orase[0], "copie:", copie[0])
}
Rezultat
[Iași Cluj] [Cluj Arad Sibiu] [Sibiu Brașov]
după modificare: [Iași CLUJ Arad Sibiu Brașov]
original: Iași copie: Galați
Exemplul 3: Ștergere, inserare și sortare cu pachetul slices
package main
import (
"fmt"
"slices"
)
func main() {
note := []int{7, 10, 4, 9, 8}
note = slices.Delete(note, 2, 3) // șterge elementul de pe poziția 2
note = slices.Insert(note, 0, 6) // inserează 6 la început
slices.Sort(note)
fmt.Println(note)
fmt.Println("conține 9:", slices.Contains(note, 9))
fmt.Println("maxim:", slices.Max(note))
}
Rezultat
[6 7 8 9 10]
conține 9: true
maxim: 10
Greșeli frecvente
append(s, x)fărăs =: nu compilează (append(s, x) (value of type []int) is not used). Rezultatul luiappendtrebuie salvat.- Index peste lungime:
panic: runtime error: index out of range [5] with length 5. - Modificarea unui sub-slice crezând că este copie: schimbă și slice-ul original.
appendpe un sub-slice poate scrie peste elementele originalului dacă mai există capacitate. Limitează capacitatea cus[a:b:b]sau clonează.
Comenzi înrudite
append: Adaugă elemente la finalul unui slice și returnează slice-ul rezultat, mărind memoria când e nevoie.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.array-uri: Șir cu număr fix de elemente de același tip; lungimea face parte din tip, iar atribuirea copiază tot.range: Parcurge într-un for elementele unui slice, array, map, text, canal, număr sau iterator.