Sobes.tech
Junior

Kuidas töötavad slices Go-s?

sobes.tech AI

Vastus AI-lt

Slicing on kerge kest üle massiivi. See ei hoia andmeid ise, vaid viitab põhimassiivile.

Slicing struktuur:

  • Viide põhimassiivile: Aadress esimesele elemendile mälus.
  • Pikkus (Length): Slicingus olevate elementide arv.
  • Võimsus (Capacity): Põhimassiivi elementide arv, mis on saadaval alates slicing viitest.
// Näide slicing deklaratsioonist
var s []int
s = append(s, 1, 2, 3) // Elementide lisamine

// Slicing s sisemine esitusviis (lihtsustatud)
// struct SliceHeader {
//     Data uintptr // Viide põhimassiivile
//     Len int      // Slicing pikkus
//     Cap int      // Võimsus
// }
  • Kui luuakse slicing kasutades make([]T, length, capacity), siis luuakse põhimassiiv määratud võimsusega ning sellele viitab slicing määratud pikkusega.
  • Kui kasutatakse lõiku massiivist või teisest slicingust (näiteks arr[low:high:max]), siis luuakse uus slicing, mis viitab samale mäluala, kuid erineva viite, pikkuse ja võimsusega.
  • append operatsioon võib põhjustada mälu ümberpaigutamist. Kui praegune võimsus ei ole piisav uute elementide lisamiseks, loob Go suurema põhimassiivi, kopeerib sinna vana ning uuendab slicing viidet uuele massiivile. Seda nimetatakse reallocation.
  • Slicingud edastatakse väärtusena, kuid kuna need sisaldavad viidet põhimassiivile, on muudatused (indeksitava kaudu) nähtavad kõigis slicingutes, mis viitavad samale põhimassiivile.
  • Pikkuse muutmine lõiguga ei mõjuta põhimassiivi, kuid võib piirata juurdepääsu osadele andmetele.
Omadus Pikkus (Length) Võimsus (Capacity)
Definitsioon Tegelik elementide arv slicingus Maksimaalne elementide arv, mis võib olla slicingus ilma reallocationita
Juurdepääs Kasutatakse elementidele juurdepääsuks (s[i]) Määrab, kui palju veel elemente saab append-iga lisada enne reallocationi
Saamine len(s) cap(s)
// Näide võimsuse ja pikkusega töötamisest
s := make([]int, 0, 5) // Pikkus 0, võimsus 5
fmt.Println(len(s), cap(s)) // 0 5

s = append(s, 1, 2) // Kaks elementi lisada
fmt.Println(len(s), cap(s)) // 2 5

s = append(s, 3, 4, 5, 6) // Veel neli elementi lisada, vaja reallocationi
fmt.Println(len(s), cap(s)) // 6 10 (võimsus suurenes)