Sobes.tech
Junior

Hogyan működnek a szeletek a Go-ban?

sobes.tech MI

Válasz az MI-től

A szelet (slice) egy könnyű burkolat egy tömb felett. Nem tárol adatokat önmagában, hanem egy alap tömbre hivatkozik.

A szelet szerkezete:

  • Mutató az alap tömbre: A szelet első elemének címe a memóriában.
  • Hossz (Length): A szeletben lévő elemek száma.
  • Kapacitás (Capacity): Az alap tömbben lévő elemek száma, amelyek elérhetők a szelet mutatójától kezdve.
// Példa egy szelet deklarálására
var s []int
s = append(s, 1, 2, 3) // Elemek hozzáadása

// A s szelet belső reprezentációja (egyszerűsített)
// struct SliceHeader {
//     Data uintptr // Mutató az alap tömbre
//     Len int      // A szelet hossza
//     Cap int      // A szelet kapacitása
// }
  • A make([]T, length, capacity) segítségével létrehozott szelet egy adott kapacitású alap tömböt hoz létre, és egy szeletet, amely erre hivatkozik a megadott hosszúsággal.
  • Egy tömb vagy más szelet szeletelésekor (pl., arr[low:high:max]) egy új szelet jön létre, amely ugyanarra a memória területre hivatkozik, de más mutatókkal, hosszúsággal és kapacitással.
  • A append művelet memória újraelosztást eredményezhet. Ha a jelenlegi kapacitás nem elegendő új elemek hozzáadásához, a Go egy nagyobb alap tömböt hoz létre, átmásolja a régi elemeket, és frissíti a szelet mutatóját az új tömbre. Ezt nevezik reallokációnak. Az kapacitás növekedése az append során exponenciális (duplázódik egy bizonyos méretig, majd lassul).
  • A szeletek érték szerint kerülnek átadásra, de mivel tartalmaznak mutatót az alap tömbre, a szelet elemeinek módosításai (indexen keresztül) minden olyan szeletben láthatók, amely ugyanarra a tömbre mutat.
  • A szelet hosszának módosítása szeleteléssel nem befolyásolja az alap tömböt, de korlátozhatja a hozzáférést a tömb egy részéhez.

Táblázat: Hossz (Length) és Kapacitás (Capacity) összehasonlítása

Jellemző Hossz (Length) Kapacitás (Capacity)
Meghatározás A szelet tényleges elemeinek száma A maximális elem szám, amit a szelet reallokáció nélkül tartalmazhat
Hozzáférés Az elemekhez való hozzáféréshez (s[i]) Meghatározza, hogy hány további elemet lehet hozzáadni append-tel reallokáció előtt
Lekérdezés len(s) cap(s)
// Példa a kapacitással és hosszúsággal való munkára
s := make([]int, 0, 5) // Hossz 0, kapacitás 5
fmt.Println(len(s), cap(s)) // 0 5

s = append(s, 1, 2) // 2 elem hozzáadása
fmt.Println(len(s), cap(s)) // 2 5

s = append(s, 3, 4, 5, 6) // 4 további elem hozzáadása, reallokáció szükséges
fmt.Println(len(s), cap(s)) // 6 10 (a kapacitás növekedett)