Sobes.tech
Junior

Go'догу slices кантип иштейт?

sobes.tech AI

AIден жооп

Слайс — бул массивдин үстүнө жеңил кабык. Ал өзү маалымат сактабайт, тескерисинче, негизги массивге шилтеме кылат.

Слайс структурасы:

  • Негизги массивге шилтеме: Памятьта биринчи элементтин дареги.
  • Узундук (Length): Слайстагы элементтердин саны.
  • Капаситет (Capacity): Негизги массивдеги, слайс көрсөткөн жерден баштап, жеткиликтүү элементтердин саны.
// Слайс декларациясынын мисалы
var s []int
s = append(s, 1, 2, 3) // Элементтерди кошуу

// Слайс sдин ички көрүнүшү (жөнөкөйлөштүрүлгөн)
// struct SliceHeader {
//     Data uintptr // Негизги массивге шилтеме
//     Len int      // Слайстын узундугу
//     Cap int      // Капаситети
// }
  • make([]T, length, capacity) аркылуу слайс түзүлгөндө, белгиленген капаситет менен негизги массив түзүлөт жана ал сылтамалуу болот.
  • arr[low:high:max] сыяктуу кесим колдонуу менен жаңы слайс түзүлөт, ал ошол эле негизги массивдин бөлүгүн көрсөтөт, бирок башка шилтемеге, узундукка жана капаситетке ээ болот.
  • append операциясы эс тутумдун кайра бөлүштүрүлүшүнө алып келиши мүмкүн. Эгер учурдагы капаситет жаңы элементтерди кошууга жетишсиз болсо, Go жаңы, чоңураак негизги массив түзүп, эски массивдин элементтерин көчүрүп, слайс шилтемесин жаңы массивге жаңыртат. Бул reallocation деп аталат.
  • Слайсдар маанилер аркылуу өткөрүлөт, бирок алар негизги массивге шилтеме камтыгандыктан, алардын элементтериндеги өзгөртүүлөр (индекс аркылуу) бардык шилтемелерде көрүнөт.
  • Слайсдын узундугун кесим аркылуу өзгөртүү негизги массивди өзгөртпөйт, бирок негизги массивдин бөлүктөрүнө жетүүнү чектей алат.
Өзгөчөлүк Узактык (Length) Капаситет (Capacity)
Түшүндүрмө Слайстагы чындыкта бар элементтердин саны Капаситет — слайска кошулчу эң көп элементтердин саны, кайра бөлүштүрүү болбостон
Жеткиликтүүлүк s[i] аркылуу элементтерге жетүү append аркылуу кошуу алдында дагы канча элемент кошулушу мүмкүн экенин аныктоо
Алып келүү len(s) cap(s)
// Капаситет жана узундук менен иштөө мисалы
s := make([]int, 0, 5) // Узактык 0, капаситет 5
fmt.Println(len(s), cap(s)) // 0 5

s = append(s, 1, 2) // Эки элемент кошуу
fmt.Println(len(s), cap(s)) // 2 5

s = append(s, 3, 4, 5, 6) // дагы 4 элемент кошуу, кайра бөлүштүрүү керек
fmt.Println(len(s), cap(s)) // 6 10 (капаситет көбөйдү)