Sobes.tech
Junior

Kaip veikia slices Go?

sobes.tech AI

Atsakymas iš AI

Slicing yra lengvas apvalkalas virš masyvo. Jis pats nesaugo duomenų, o nuoroda į pagrindinį masyvą.

Slicing struktūra:

  • Nuoroda į pagrindinį masyvą: Adresas pirmo elemento atmintyje.
  • Ilgis (Length): Elementų skaičius slicing'e.
  • Talpa (Capacity): Elementų skaičius pagrindiniame masyve, prieinamas nuo slicing nuorodos.
// Pavyzdys, kaip deklaruoti slicing
var s []int
s = append(s, 1, 2, 3) // Pridėti elementus

// Vidinė slicing s reprezentacija (paprasta)
// struct SliceHeader {
//     Data uintptr // Nuoroda į pagrindinį masyvą
//     Len int      // Slicing ilgis
//     Cap int      // Talpa
// }
  • Kuriant slicing naudojant make([]T, length, capacity) sukuriamas pagrindinis masyvas su nurodyta talpa ir slicing, kuris nuoroda į jį su nurodytu ilgiu.
  • Naudojant iškarpą iš masyvo ar kito slicing (pvz., arr[low:high:max]) sukuriamas naujas slicing, kuris nuoroda į tą pačią atminties sritį kaip ir pagrindinis masyvas, bet su kitu nuoroda, ilgiu ir talpa.
  • append operacija gali sukelti atminties perplanavimą. Jei dabartinė talpa nėra pakankama naujiems elementams pridėti, Go sukuria didesnį pagrindinį masyvą, kopijuoja į jį senąjį ir atnaujina nuorodą į naująjį masyvą. Tai vadinama reallocation.
  • Slicingai perduodami kaip reikšmė, bet kadangi jie turi nuorodą į pagrindinį masyvą, pakeitimai (per indeksą) bus matomi visuose slicing'uose, kurie nuoroda į tą patį pagrindinį masyvą.
  • Slicing ilgį keisti per iškarpą nekeičia pagrindinio masyvo, bet gali apriboti prieigą prie dalies duomenų.
Savybė Ilgis (Length) Talpa (Capacity)
Apibrėžimas Faktinis elementų skaičius slicing'e Maksimalus elementų skaičius, kuris gali būti slicing be perplanavimo
Prieiga Naudojama prieigai prie elementų (s[i]) Nustato, kiek dar elementų galima pridėti append prieš reallocation
Gauti len(s) cap(s)
// Pavyzdys, kaip dirbti su talpa ir ilgiu
s := make([]int, 0, 5) // Ilgis 0, talpa 5
fmt.Println(len(s), cap(s)) // 0 5

s = append(s, 1, 2) // Pridėti 2 elementus
fmt.Println(len(s), cap(s)) // 2 5

s = append(s, 3, 4, 5, 6) // Dar pridėti 4 elementus, reikalinga reallocation
fmt.Println(len(s), cap(s)) // 6 10 (talpa padidėjo)