Junior
Ինչպես են աշխատում slices-ները Go-ում?
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) // 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 (հավաքածուն մեծացել է)