Sobes.tech
Junior

Ako fungujú slices v Go?

sobes.tech AI

Odpoveď od AI

Slicing je ľahký obal nad poľom. Sám o sebe neukladá dáta, iba odkazuje na základné pole.

Štruktúra slicing:

  • Ukazovateľ na základné pole: Adresa prvého prvku v pamäti.
  • Dĺžka (Length): Počet prvkov v slicing.
  • Kapacita (Capacity): Počet prvkov v základnom poli dostupných od ukazovateľa slicing.
// Príklad deklarácie slicing
var s []int
s = append(s, 1, 2, 3) // Pridanie prvkov

// Vnútorné zobrazenie slicing s (zjednodušené)
// struct SliceHeader {
//     Data uintptr // Ukazovateľ na základné pole
//     Len int      // Dĺžka slicing
//     Cap int      // Kapacita slicing
// }
  • Pri vytváraní slicing pomocou make([]T, length, capacity) sa vytvorí základné pole s danou kapacitou a slicing, ktorý naň odkazuje s danou dĺžkou.
  • Pri použití rezu na pole alebo inom slicing (napríklad, arr[low:high:max]) sa vytvorí nový slicing, ktorý odkazuje na rovnakú oblasť v pamäti základného poľa, ale s iným ukazovateľom, dĺžkou a kapacitou.
  • Operácia append môže viesť k prealokácii pamäti. Ak aktuálna kapacita nestačí na pridanie nových prvkov, Go vytvorí nové väčšie základné pole, skopíruje do neho prvky starého poľa a aktualizuje ukazovateľ slicing na nové pole. Toto sa nazýva reallokácia. Rast kapacity pri append je exponenciálny (zdvojuje sa do určitej veľkosti, potom rast spomaľuje).
  • Slicingy sa predávajú podľa hodnoty, ale pretože obsahujú ukazovateľ na základné pole, zmeny prvkov slicing (cez index) budú viditeľné vo všetkých slicingoch odkazujúcich na ten istý základný pole.
  • Zmena dĺžky slicing cez rez neovplyvňuje základné pole, ale môže obmedziť prístup k časti dát základného poľa.

Tabuľka: Porovnanie Length a Capacity

Charakteristika Dĺžka (Length) Kapacita (Capacity)
Definícia Skutočný počet prvkov v slicing Maximálny počet prvkov, ktoré môžu byť v slicing bez prealokácie
Prístup Používa sa na prístup k prvkom (s[i]) Určuje, koľko ďalších prvkov možno pridať cez append pred reallokáciou
Získanie len(s) cap(s)
// Príklad práce s kapacitou a dĺžkou
s := make([]int, 0, 5) // Dĺžka 0, kapacita 5
fmt.Println(len(s), cap(s)) // 0 5

s = append(s, 1, 2) // Pridanie 2 prvkov
fmt.Println(len(s), cap(s)) // 2 5

s = append(s, 3, 4, 5, 6) // Pridanie ďalších 4 prvkov, je potrebná reallokácia
fmt.Println(len(s), cap(s)) // 6 10 (kapacita sa zväčšila)