Sobes.tech
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 append poate 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 la append este 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)