Junior
Cum funcționează slices în Go?
sobes.tech AI
Răspuns de la AI
Un slice este o înveliș ușor peste un array. Nu stochează datele singur, ci face referire la un array de bază.
Structura slice-ului:
- Pointer către array-ul de bază: Adresa primului element al slice-ului în memorie.
- Lungime (Length): Numărul de elemente din slice.
- Capacitate (Capacity): Numărul de elemente din array-ul de bază, disponibile de la pointer-ul slice-ului.
// Exemplu de declarare a unui slice
var s []int
s = append(s, 1, 2, 3) // Adăugarea elementelor
// Reprezentarea internă a slice-ului s (simplificată)
// struct SliceHeader {
// Data uintptr // Pointer către array-ul de bază
// Len int // Lungimea slice-ului
// Cap int // Capacitatea slice-ului
// }
- Crearea unui slice cu
make([]T, length, capacity)creează un array de bază cu capacitatea specificată, iar slice-ul care face referire la el are lungimea indicată. - Când se folosește o secțiune pe un array sau alt slice (de exemplu,
arr[low:high:max]), se creează un nou slice care face referire la aceeași zonă de memorie a array-ului de bază, dar cu pointeri, lungime și capacitate diferite. - Operația
appendpoate duce la realocarea memoriei. Dacă capacitatea curentă nu este suficientă pentru a adăuga noi elemente, Go creează un nou array de bază mai mare, copiază elementele vechi și actualizează pointerul slice-ului către noul array. Aceasta se numește realocare. Creșterea capacității laappendeste exponențială (se dublează până la o anumită dimensiune, apoi încetinește). - Slice-urile sunt transmise prin valoare, dar deoarece conțin un pointer către array-ul de bază, modificările elementelor (prin index) vor fi vizibile în toate slice-urile care fac referire la același array.
- Modificarea lungimii slice-ului prin secționare nu afectează array-ul de bază, dar poate limita accesul la o parte din datele din array-ul de bază.
Tabel: Compararea Length și Capacity
| Caracteristică | Lungime (Length) | Capacitate (Capacity) |
|---|---|---|
| Definiție | Numărul real de elemente din slice | Numărul maxim de elemente pe care le poate conține slice-ul fără realocare |
| Acces | Folosit pentru accesarea elementelor (s[i]) | Determină câte elemente suplimentare pot fi adăugate cu append înainte de realocare |
| Obținere | len(s) |
cap(s) |
// Exemplu de lucru cu capacitatea și lungimea
s := make([]int, 0, 5) // Lungime 0, capacitate 5
fmt.Println(len(s), cap(s)) // 0 5
s = append(s, 1, 2) // Adăugarea a 2 elemente
fmt.Println(len(s), cap(s)) // 2 5
s = append(s, 3, 4, 5, 6) // Adăugarea a încă 4 elemente, necesită realocare
fmt.Println(len(s), cap(s)) // 6 10 (capacitatea a crescut)