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. appendoperatsioon 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)