9-bo‘lim
Massivlar va slicelar
Qat'iy uzunlikdagi massivlar, slice ning ichki tuzilishi, append va cap, kesish, nusxalash hamda umumiy xotira tuzog'i.
Ushbu bo‘lim mundarijasi
Go da ro'yxat uchun ikki tur bor: massiv va slice. Amalda deyarli har doim ikkinchisi ishlatiladi, lekin birinchisini tushunish kerak - slice uning ustiga qurilgan.
Massiv - uzunligi qat'iy #
package main
import "fmt"
func main() {
var ballar [3]int
fmt.Println(ballar)
ballar[0] = 85
ballar[1] = 92
fmt.Println(ballar, len(ballar))
shaharlar := [3]string{"Namangan", "Andijon", "Buxoro"}
fmt.Println(shaharlar)
avto := [...]int{1, 2, 3, 4, 5}
fmt.Println(avto, len(avto))
}
[0 0 0]
[85 92 0] 3
[Namangan Andijon Buxoro]
[1 2 3 4 5] 5
Massivning uzunligi uning turining bir qismi: [3]int va
[5]int - butunlay boshqa turlar.
[...]int{...} - "uzunlikni o'zing sana" degani.
Massivni boshqa o'zgaruvchiga berganingizda yoki funksiyaga uzatganingizda, butun mazmuni nusxalanadi:
a := [3]int{1, 2, 3}
b := a
b[0] = 99
// a hali ham [1 2 3]
Ming elementli massivni funksiyaga uzatsangiz, ming element nusxalanadi. Aynan shuning uchun amalda slice ishlatiladi - u nusxalanmaydi.
Slice - o'zgaruvchan uzunlik #
package main
import "fmt"
func main() {
ballar := []int{85, 92, 78}
fmt.Println(ballar, len(ballar))
ballar = append(ballar, 95)
fmt.Println(ballar, len(ballar))
ballar = append(ballar, 60, 71)
fmt.Println(ballar)
boshqa := []int{100, 200}
ballar = append(ballar, boshqa...)
fmt.Println(ballar)
}
[85 92 78] 3
[85 92 78 95] 4
[85 92 78 95 60 71]
[85 92 78 95 60 71 100 200]
E'tibor bering: []int - kvadrat qavs ichida hech narsa yo'q.
Aynan shu massivdan farq qiladi.
append yangi slice qaytaradi, shuning uchun natijani qayta
o'zlashtirish kerak: ballar = append(ballar, ...).
Bu Go dagi eng ko'p uchraydigan yangi boshlovchi xatosi:
append(ballar, 95) // natija tashlab yuborildi
ballar = append(ballar, 95) // to'g'ri
Birinchi shakl kompilyatsiya bo'ladi, lekin hech narsa qilmaydi.
Yaxshiyamki, go vet buni topadi.
Ichida nima bor #
Slice - uch qismdan iborat kichik tuzilma:
package main
import "fmt"
func main() {
ballar := make([]int, 3, 5)
fmt.Println(ballar, len(ballar), cap(ballar))
ballar = append(ballar, 10)
fmt.Println(ballar, len(ballar), cap(ballar))
ballar = append(ballar, 20)
fmt.Println(len(ballar), cap(ballar))
ballar = append(ballar, 30)
fmt.Println(len(ballar), cap(ballar))
}
[0 0 0] 3 5
[0 0 0 10] 4 5
5 5
6 10
make([]int, 3, 5) - uzunligi 3, sig'imi 5 bo'lgan slice.
Oltinchi element qo'shilganda sig'im yetmay qoldi va Go yangi, ikki barobar katta massiv yaratdi.
Nechta element bo'lishini bilsangiz, sig'imni darhol ayting:
natija := make([]string, 0, len(manba))
Aks holda append slice o'sgani sari bir necha marta yangi massiv
yaratib, eskisini ko'chirishga majbur bo'ladi.
Bu darslikdagi 7-bo'limdagi qolla funksiyasida aynan shunday
qilingan edi.
Kesish #
package main
import "fmt"
func main() {
harflar := []string{"a", "b", "c", "d", "e"}
fmt.Println(harflar[1:3])
fmt.Println(harflar[:2])
fmt.Println(harflar[3:])
fmt.Println(harflar[:])
}
[b c]
[a b]
[d e]
[a b c d e]
[boshi:oxiri] - boshi kiradi, oxiri kirmaydi. Shuning
uchun [1:3] ikki element beradi.
Ikkala chekka ham tashlab ketilishi mumkin.
Umumiy xotira tuzog'i #
package main
import "fmt"
func main() {
asl := []int{1, 2, 3, 4, 5}
qism := asl[1:3]
fmt.Println("asl:", asl)
fmt.Println("qism:", qism)
qism[0] = 999
fmt.Println("o'zgartirgandan keyin")
fmt.Println("asl:", asl)
fmt.Println("qism:", qism)
}
asl: [1 2 3 4 5]
qism: [2 3]
o'zgartirgandan keyin
asl: [1 999 3 4 5]
qism: [999 3]
qism - asl slicening nusxasi emas. U o'sha massivga
ko'rsatuvchi yangi oyna.
Shuning uchun qism orqali yozganingizda asl ham o'zgaradi.
Bu Go dagi eng nozik tuzoqlardan biri: funksiyaga slicening bir bo'lagini uzatsangiz, funksiya asl ma'lumotni buzishi mumkin.
Mustaqil nusxa kerak bo'lsa, copy ishlating - u quyida.
copy bilan haqiqiy nusxa #
package main
import "fmt"
func main() {
asl := []int{1, 2, 3, 4, 5}
nusxa := make([]int, len(asl))
kochirildi := copy(nusxa, asl)
nusxa[0] = 999
fmt.Println("ko'chirildi:", kochirildi)
fmt.Println("asl:", asl)
fmt.Println("nusxa:", nusxa)
}
ko'chirildi: 5
asl: [1 2 3 4 5]
nusxa: [999 2 3 4 5]
copy nechta element ko'chirilganini qaytaradi. U ikki slicening
kichigi qadar ko'chiradi.
nil slice va bo'sh slice #
package main
import "fmt"
func main() {
var bosh []int
tayyor := []int{}
fmt.Println(bosh == nil, len(bosh))
fmt.Println(tayyor == nil, len(tayyor))
bosh = append(bosh, 1)
fmt.Println(bosh)
}
true 0
false 0
[1]
nil slicega ham append qilish mumkin - Go massivni o'zi yaratadi.
Shuning uchun var natija []int deb boshlash mutlaqo normal va
odatiy Go uslubi.
slices paketi #
package main
import (
"fmt"
"slices"
)
func main() {
sonlar := []int{5, 2, 8, 1, 9}
slices.Sort(sonlar)
fmt.Println(sonlar)
fmt.Println(slices.Contains(sonlar, 8))
fmt.Println(slices.Index(sonlar, 8))
fmt.Println(slices.Max(sonlar), slices.Min(sonlar))
slices.Reverse(sonlar)
fmt.Println(sonlar)
shaharlar := []string{"Namangan", "Andijon"}
fmt.Println(slices.Equal(shaharlar, []string{"Namangan", "Andijon"}))
}
[1 2 5 8 9]
true
3
9 1
[9 8 5 2 1]
true
slices paketi Go 1.21 da standart kutubxonaga qo'shildi. Undan
oldin bu ishlarni har kim o'zi yozardi.
| Funksiya | Nima qiladi |
|---|---|
slices.Sort | Saralaydi (joyida) |
slices.Contains | Bormi |
slices.Index | O'rni (yo'q bo'lsa -1) |
slices.Max / Min | Eng katta / kichik |
slices.Reverse | Teskari qiladi (joyida) |
slices.Equal | Ikki slice teng mi |
slices.Sort yangi slice qaytarmaydi - u mavjudini saralaydi.
Aslini saqlash kerak bo'lsa, avval copy bilan nusxa oling. Yoki
slices.Sorted funksiyasidan foydalaning.
Xuddi shu narsa slices.Reverse uchun ham to'g'ri.
Ikki o'lchamli slice #
package main
import "fmt"
func main() {
jadval := make([][]int, 3)
for i := range jadval {
jadval[i] = make([]int, 3)
for j := range jadval[i] {
jadval[i][j] = (i + 1) * (j + 1)
}
}
for _, qator := range jadval {
fmt.Println(qator)
}
}
[1 2 3]
[2 4 6]
[3 6 9]
Go da haqiqiy ikki o'lchamli slice yo'q - bu slicelar slicesi. Har bir qatorni alohida yaratish kerak.
Elementni o'chirish #
package main
import (
"fmt"
"slices"
)
func main() {
shaharlar := []string{"Namangan", "Andijon", "Buxoro", "Xiva"}
shaharlar = slices.Delete(shaharlar, 1, 2)
fmt.Println(shaharlar)
shaharlar = append(shaharlar[:1], shaharlar[2:]...)
fmt.Println(shaharlar)
}
[Namangan Buxoro Xiva]
[Namangan Xiva]
slices.Delete(s, i, j) - i dan j gacha bo'lgan elementlarni
olib tashlaydi.
Ikkinchi shakl - eski, qo'lda yozilgan usul. Uni eski kodda ko'p
uchratasiz, lekin yangi kodda slices.Delete tozaroq.
- Uch elementli massiv yaratib, nol qiymatlarini ko'ring.
- Massivni nusxalab, nusxa mustaqil ekanini isbotlang.
appendbilan slicega uch element qo'shing.makebilan sig'im bering vacapo'sishini kuzating.- Slice ni kesib, uch xil shaklni sinang.
- Kesma asl ma'lumotni o'zgartirishini ko'rsating.
copybilan mustaqil nusxa oling.nilslicegaappendqiling.slices.Sortvaslices.Containsni ishlating.- Ikki o'lchamli jadval yasab, ko'paytirishni chiqaring.
Xulosa #
- Massivning uzunligi turining bir qismi va u nusxalanadi.
- Slice - uch maydonli tuzilma: ko'rsatkich,
lenvacap. appendyangi slice qaytaradi - natijani albatta o'zlashtiring.- Sig'im yetmasa, Go yangi, kattaroq massiv yaratadi;
makebilan sig'imni oldindan bering. [i:j]daikiradi,jkirmaydi.- Kesma nusxa emas - u asl massivga ko'rsatadi; mustaqil nusxa
uchun
copy. nilslice ishlatishga tayyor: unga darholappendqilish mumkin.slicespaketi (Go 1.21) saralash, qidirish va o'chirishni beradi, lekinSortvaReversejoyida ishlaydi.
Keyingi bo'limda maplarni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.