9-bo‘lim

Massivlar va slicelar

Qat'iy uzunlikdagi massivlar, slice ning ichki tuzilishi, append va cap, kesish, nusxalash hamda umumiy xotira tuzog'i.

🕑 14 daqiqa o‘qish 📄 661 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Massiv - uzunligi qat'iy
  2. Slice - o'zgaruvchan uzunlik
  3. Ichida nima bor
  4. Kesish
  5. Umumiy xotira tuzog'i
  6. copy bilan haqiqiy nusxa
  7. nil slice va bo'sh slice
  8. slices paketi
  9. Ikki o'lchamli slice
  10. Elementni o'chirish
  11. Xulosa

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 #

Go
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))
}
Natija
[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.

Massiv nusxalanadi

Massivni boshqa o'zgaruvchiga berganingizda yoki funksiyaga uzatganingizda, butun mazmuni nusxalanadi:

Go
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 #

Go
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)
}
Natija
[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, ...).

append natijasini albatta o'zlashtiring

Bu Go dagi eng ko'p uchraydigan yangi boshlovchi xatosi:

Go
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:

Slice ichida uch maydon bor slice ptr -> massivga len 3 (ko'rinadigan) cap 5 (joy bor) Asosiy massiv 85 92 78 - - len = 3 cap = 5 append cap ichiga sig'sa - o'sha massivga yozadi. Sig'masa - yangi, kattaroq massiv yaratiladi.
Go
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))
}
Natija
[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.

make bilan sig'imni oldindan bering

Nechta element bo'lishini bilsangiz, sig'imni darhol ayting:

Go
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 #

Go
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[:])
}
Natija
[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 #

Go
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)
}
Natija
asl: [1 2 3 4 5]
qism: [2 3]
o'zgartirgandan keyin
asl: [1 999 3 4 5]
qism: [999 3]
Kesma nusxa emas

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 #

Go
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)
}
Natija
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 #

Go
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)
}
Natija
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 #

Go
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"}))
}
Natija
[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.

FunksiyaNima qiladi
slices.SortSaralaydi (joyida)
slices.ContainsBormi
slices.IndexO'rni (yo'q bo'lsa -1)
slices.Max / MinEng katta / kichik
slices.ReverseTeskari qiladi (joyida)
slices.EqualIkki slice teng mi
Sort asl slicening o'zini o'zgartiradi

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 #

Go
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)
    }
}
Natija
[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 #

Go
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)
}
Natija
[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.

Amaliy topshiriq
  1. Uch elementli massiv yaratib, nol qiymatlarini ko'ring.
  2. Massivni nusxalab, nusxa mustaqil ekanini isbotlang.
  3. append bilan slicega uch element qo'shing.
  4. make bilan sig'im bering va cap o'sishini kuzating.
  5. Slice ni kesib, uch xil shaklni sinang.
  6. Kesma asl ma'lumotni o'zgartirishini ko'rsating.
  7. copy bilan mustaqil nusxa oling.
  8. nil slicega append qiling.
  9. slices.Sort va slices.Contains ni ishlating.
  10. Ikki o'lchamli jadval yasab, ko'paytirishni chiqaring.

Xulosa #

  • Massivning uzunligi turining bir qismi va u nusxalanadi.
  • Slice - uch maydonli tuzilma: ko'rsatkich, len va cap.
  • append yangi slice qaytaradi - natijani albatta o'zlashtiring.
  • Sig'im yetmasa, Go yangi, kattaroq massiv yaratadi; make bilan sig'imni oldindan bering.
  • [i:j] da i kiradi, j kirmaydi.
  • Kesma nusxa emas - u asl massivga ko'rsatadi; mustaqil nusxa uchun copy.
  • nil slice ishlatishga tayyor: unga darhol append qilish mumkin.
  • slices paketi (Go 1.21) saralash, qidirish va o'chirishni beradi, lekin Sort va Reverse joyida ishlaydi.

Keyingi bo'limda maplarni o'rganamiz.

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.