Go’da map ma’lumot turi
map kalit-qiymat juftlarini saqlaydi. Slice’da element indeks orqali topilsa, mapda unga mazmunli kalit orqali murojaat qilinadi. Masalan, mahsulot narxini kodi orqali yoki foydalanuvchini ID orqali topish mumkin.
Bitta mapdagi barcha kalitlar bir xil turda, barcha qiymatlar ham bir xil turda bo‘ladi. Har bir kalit yagona, lekin turli kalitlar bir xil qiymatga ega bo‘lishi mumkin.
map yaratish
map[KalitTuri]QiymatTuri turini literal yoki make bilan yaratish mumkin:
package main
import "fmt"
func main() {
narxlar := map[string]int{
"non": 4_000,
"sut": 12_000,
"guruch": 18_000,
}
ombor := make(map[string]int)
ombor["non"] = 25
fmt.Println("Sut narxi:", narxlar["sut"])
fmt.Println("Non miqdori:", ombor["non"])
}
Natija:
make(map[string]int) yozishga tayyor bo‘sh map qaytaradi. makega taxminiy elementlar sonini berish ham mumkin: make(map[string]int, 100). Bu uzunlikni belgilamaydi, faqat oldindan joy tayyorlashga yordam berishi mumkin.
nil va bo‘sh map
mapning nol qiymati nil:
package main
import "fmt"
func main() {
var nilMap map[string]int
boshMap := make(map[string]int)
fmt.Println(len(nilMap), nilMap == nil)
fmt.Println(len(boshMap), boshMap == nil)
fmt.Println(nilMap["yo‘q"])
}
Natija:
nil map’dan o‘qish, uning uzunligini olish, u bo‘ylab yurish va delete qilish xavfsiz. Ammo unga qiymat yozish panic: assignment to entry in nil map xatosini beradi. Yozishdan oldin literal yoki make bilan tayyorlang.
Kalit mavjudligini tekshirish
Mavjud bo‘lmagan kalit o‘qilsa, qiymat turining nol qiymati qaytadi. Bu kalit yo‘qligini har doim ham bildirmaydi, chunki nol qiymat ataylab saqlangan bo‘lishi mumkin. “Vergul, ok” (comma ok) shakli bu ikki holatni ajratadi:
package main
import "fmt"
func main() {
ballar := map[string]int{"Ali": 0}
ball, bor := ballar["Ali"]
fmt.Println("Ali:", ball, bor)
ball, bor = ballar["Vali"]
fmt.Println("Vali:", ball, bor)
}
Natija:
Qiymat kerak bo‘lmasa, _, bor := ballar["Ali"] deb yoziladi.
Qiymatni yangilash va o‘chirish
Mavjud kalitga qayta qiymat berish eski qiymatni almashtiradi. delete kalitni o‘chiradi; kalit mavjud bo‘lmasa ham xato bermaydi.
package main
import "fmt"
func main() {
foydalanuvchi := map[string]string{"ism": "Sardor", "shahar": "Toshkent"}
foydalanuvchi["ism"] = "Elbek"
delete(foydalanuvchi, "shahar")
fmt.Println(foydalanuvchi["ism"])
_, bor := foydalanuvchi["shahar"]
fmt.Println("Shahar mavjud:", bor)
}
Natija:
Qaysi turlar kalit bo‘la oladi?
Kalit turi == va != bilan taqqoslanadigan bo‘lishi kerak. Son, satr, bool, pointer, channel, interface hamda faqat taqqoslanadigan maydonlardan iborat array va struct kalit bo‘la oladi. Slice, map va funksiya kalit bo‘la olmaydi.
float64 texnik jihatdan kalit bo‘la oladi, ammo NaN o‘ziga ham teng emas. Amaliy kodda kasrli sonni kalit qilishdan ehtiyot bo‘ling.
range va tartib
map bo‘ylab yurish tartibi kafolatlanmagan:
package main
import (
"fmt"
"sort"
)
func main() {
yoshlar := map[string]int{"Ali": 24, "Vali": 31, "Lola": 27}
kalitlar := make([]string, 0, len(yoshlar))
for ism := range yoshlar {
kalitlar = append(kalitlar, ism)
}
sort.Strings(kalitlar)
for _, ism := range kalitlar {
fmt.Println(ism, yoshlar[ism])
}
}
Natija:
Barqaror chiqish kerak bo‘lsa, kalitlarni slice’ga yig‘ib saralang. Testlar, loglar va foydalanuvchiga ko‘rsatiladigan ro‘yxatlarda tasodifiy tartibga tayanmang.
Tayinlash, funksiyaga uzatish va parallel ishlash
b := a barcha elementlarni chuqur nusxalamaydi. a va b bir xil asosiy map ma’lumotiga murojaat qiladi; biri orqali o‘zgarish ikkinchisida ko‘rinadi. Mustaqil nusxa kerak bo‘lsa, yangi map yaratib juftlarni ko‘chiring.
Oddiy map bir vaqtda bir nechta goroutine tomonidan yozish uchun xavfsiz emas. Parallel kirishda sync.Mutex, sync.RWMutex, kanal orqali egalik yoki vazifaga mos bo‘lsa sync.Map kabi sinxronlash kerak. Bu mavzu concurrency darslarida batafsil o‘rganiladi.
Xulosa
mapqiymatni yagona kalit orqali topadi.- Mavjud bo‘lmagan kalit nol qiymat qaytaradi; mavjudlikni
value, ok := m[key]bilan tekshiring. nilmap’dan o‘qish mumkin, yozish mumkin emas.- Iteratsiya tartibi kafolatlanmaydi.
maptayinlanganda elementlar chuqur nusxalanmaydi va parallel yozish alohida himoya talab qiladi.
Keyingi darsda qiymatning xotira manzilini saqlaydigan ko‘rsatkichlar ko‘rib chiqiladi.