Go’da slice bilan ishlash
Slice bir xil turdagi elementlar ketma-ketligi bilan ishlash uchun mo‘ljallangan. Uning uzunligi o‘zgarishi mumkin, shu sabab API javoblari, fayldan o‘qilgan satrlar yoki bazadan kelgan yozuvlar kabi soni oldindan noma’lum ma’lumotlarda slice ko‘p ishlatiladi.
Slice elementlarning o‘zini saqlaydigan mustaqil massiv emas. U asosiy massivning (backing array) ma’lum qismiga qaraydigan kichik tavsifdir. Bu tavsifda asosiy massivga bog‘lanish, uzunlik (len) va sig‘im (cap) bor.
Slice yaratish
Slice turi []elementTuri ko‘rinishida yoziladi. Qavs ichida uzunlik yo‘qligi uni massivdan ajratadi.
package main
import "fmt"
func main() {
var bosh []int
mevalar := []string{"olma", "anor", "uzum"}
sonlar := make([]int, 3, 5)
fmt.Println(bosh, len(bosh), cap(bosh), bosh == nil)
fmt.Println(mevalar)
fmt.Println(sonlar, len(sonlar), cap(sonlar))
}
Natija:
var bo‘sh []int nol qiymatli, ya’ni nil slice yaratadi. nil slice bilan len, cap, range va append xavfsiz ishlaydi. make([]int, 3, 5) esa uchta mavjud element va jami beshta elementgacha joy tayyorlaydi.
Info
nil slice va []int{} ikkalasining uzunligi nol, lekin faqat birinchisi nilga teng. JSON kodlash kabi ayrim tashqi formatlarda ular boshqacha ko‘rinishi mumkin.
Massiv yoki slice’dan bo‘lak olish
s[past:yuqori] ifodasida pastki chegara kiradi, yuqori chegara kirmaydi:
package main
import "fmt"
func main() {
sonlar := []int{10, 20, 30, 40, 50}
qism := sonlar[1:4]
fmt.Println(qism)
qism[0] = 99
fmt.Println(sonlar)
}
Natija:
qism yangi elementlar nusxasini yaratmaydi. U sonlar bilan bir xil asosiy massivga qaraydi. Shu sabab qism[0] o‘zgarsa, sonlar[1] ham o‘zgaradi. Mustaqil nusxa kerak bo‘lsa, copy ishlatiladi.
append, uzunlik va sig‘im
append slice oxiriga element qo‘shib, yangilangan slice’ni qaytaradi. Qaytgan qiymatni saqlash kerak:
package main
import "fmt"
func main() {
sonlar := make([]int, 0, 2)
sonlar = append(sonlar, 10, 20)
fmt.Println(sonlar, len(sonlar), cap(sonlar))
sonlar = append(sonlar, 30)
fmt.Println(sonlar, len(sonlar), cap(sonlar))
}
Natijaning sig‘im qismi Go versiyasi va runtime qaroriga bog‘liq bo‘lishi mumkin. Muhim kafolat — sig‘im uzunlikdan kam bo‘lmaydi:
Joy yetarli bo‘lsa, append mavjud asosiy massivdan foydalanadi. Joy yetmasa, runtime kattaroq massiv ajratadi, elementlarni ko‘chiradi va yangi massivga qaraydigan slice qaytaradi. Sig‘imning aynan necha baravar o‘sishiga tayanib kod yozmang.
Warning
append(sonlar, 30) natijasini o‘zgaruvchiga qaytarmaslik xato. append yangi asosiy massiv ajratishi mumkin: sonlar = append(sonlar, 30) deb yozing.
Slice’lar orasidagi yashirin bog‘lanish
Bir asosiy massivni bo‘lishadigan slice’larda append kutilmagan o‘zgarish keltirishi mumkin:
package main
import "fmt"
func main() {
asl := []int{1, 2, 3, 4}
qism := asl[:2]
qism = append(qism, 99)
fmt.Println("Asl:", asl)
fmt.Println("Qism:", qism)
}
Natija:
qismning sig‘imi yetarli bo‘lgani uchun append o‘sha massivdagi uchinchi element ustiga yozdi. Bog‘lanishni uzish kerak bo‘lsa, nusxa yarating.
Mustaqil nusxa olish
copy ko‘chirilgan elementlar sonini qaytaradi. Bu son manba va qabul qiluvchi uzunliklarining kichigiga teng:
package main
import "fmt"
func main() {
asl := []int{1, 2, 3}
nusxa := make([]int, len(asl))
kochirilgan := copy(nusxa, asl)
nusxa[0] = 99
fmt.Println("Ko‘chirildi:", kochirilgan)
fmt.Println("Asl:", asl)
fmt.Println("Nusxa:", nusxa)
}
Natija:
Zamonaviy Go kodida nusxa := append([]int(nil), asl...) yoki nusxa := slices.Clone(asl) ham uchraydi. copy esa ishlash mexanizmini aniq ko‘rsatadi va barcha tegishli Go versiyalarida tushunarli.
Element o‘chirish
Slice’da alohida delete funksiyasi yo‘q. Tartibni saqlab qolish uchun ikki bo‘lak birlashtiriladi:
package main
import "fmt"
func main() {
sonlar := []int{10, 20, 30, 40}
indeks := 1
sonlar = append(sonlar[:indeks], sonlar[indeks+1:]...)
fmt.Println(sonlar)
}
Natija:
Tashqaridan kelgan indeks uchun avval 0 <= indeks && indeks < len(sonlar) shartini tekshirish kerak. Aks holda kesish panic beradi. Pointer saqlovchi katta slice’da o‘chirilgan oxirgi elementni nol qiymatga tushirish keraksiz obyektning xotirada ushlanib qolishini oldini olishi mumkin.
Funksiyaga slice uzatish
Slice tavsifi qiymat sifatida nusxalanadi, ammo nusxadagi ko‘rsatkich o‘sha asosiy massivga qaraydi. Funksiya mavjud elementlarni o‘zgartira oladi. appenddan keyingi yangi uzunlikni chaqiruvchiga yetkazish uchun slice’ni qaytarish odatiy usuldir.
Xulosa
- Slice uzunligi o‘zgaradigan ketma-ket ma’lumotlar uchun ishlatiladi.
lenmavjud elementlar sonini,capesa joriy nuqtadan asosiy massiv oxirigacha bo‘lgan sig‘imni bildiradi.- Kesib olingan slice odatda manba bilan bir xil massivni bo‘lishadi.
appendqaytargan slice saqlanishi kerak; u yangi massiv ajratishi mumkin.- Mustaqil ma’lumot kerak bo‘lsa, elementlarni
copybilan nusxalang.
Keyingi darsda kalit orqali qiymat topishga mo‘ljallangan map turi ko‘rib chiqiladi.