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
appendmôž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)