Shanraq.org Shanraq.org
Go-дағы сөздік (map): кілт пен мән
IT

Go тілі: нөлден өз блогыңызға дейін 9-сабақ (барлығы 50)

Go-дағы сөздік (map): кілт пен мән

Go курсының тоғызыншы сабағы. Сөздік, ағылшынша map: «кілт — мән» жұбы, ол тізімді теріп шығуды емес, бірден табуды береді. Жазу мен оқу, жоқ кілт неге қате емес, нөл беретіні, үтір-ok деген не, Go аралау ретін неге өзгертеді және nil-сөздік nil-тілімнен несімен қауіпті.

Не үшін керек

Өткен сабақта мақалалар тізімі қалай керек, солай өсті. Бірақ ондағы мақаланы мекенжайы бойынша табу — бүкіл тізімді аралау деген сөз: жүз мақала — жүз салыстыру, мың мақала — мың. Ал браузерге бірден жауап беру керек.

Сол үшін Go-да көп мәнді сақтаудың екінші тәсілі бар — сөздік, кодта map. Құжаттамада да, қате хабарламаларында да сол ағылшын сөзі тұрады, сондықтан екеуін де біліп қойған жөн.

Елестетіп көріңіз. Сөздік. Сіз оны керек сөзге жеткенше бірінші бетінен бастап оқымайсыз — керек әріптен бірден ашасыз. Тізімнен іздеу — түгел аралап шығу, ал сөздік бірден жауап береді.

Бірден тұтас

Жаңа қалта, go mod init sabaq08, main.go:

package main

import (
	"fmt"
	"slices"
)

func main() {
	views := map[string]int{
		"go":      120,
		"қазақша": 45,
		"веб":     30,
	}

	views["go"]++
	views["дала"] = 7

	fmt.Println("тег саны:", len(views))
	fmt.Println("go:", views["go"])
	fmt.Println("музыка:", views["музыка"])

	n, ok := views["музыка"]
	fmt.Println("мән:", n, "· мұндай кілт бар ма:", ok)

	keys := make([]string, 0, len(views))
	for k := range views {
		keys = append(keys, k)
	}
	slices.Sort(keys)

	for _, k := range keys {
		fmt.Println(k, views[k])
	}
}

Іске қоспас бұрын — төменге қарамай, оның не басып шығаратынын дауыстап айтыңыз. Содан кейін жіберіп, салыстырыңыз: айырма шыққан жер — тілді әлі білмейтін тұсыңыз.

go run . мынаны басып шығарады:

тег саны: 4
go: 121
музыка: 0
мән: 0 · мұндай кілт бар ма: false
go 121
веб 30
дала 7
қазақша 45

«музыка» деген тегті біз қоспаған едік — сонда да жауап алдық.

Талдау

map[string]int — неден неге

Жазу солдан оңға қарай оқылады: тік жақшаның ішінде кілттің түрі, дәл содан кейін мәннің түрі. map[string]int — жолдан санға: тег бойынша қаралым саны.

Кілт кез келген нәрсе бола алмайды, тек теңдікке салыстыруға келетіні: жол, сан, bool. Тілім кілт бола алмайды — себебі Go екі тілімді салыстырудан бас тартады.

Жазу және оқу

views["дала"] = 7      // жаздық
n := views["go"]       // оқыдық
views["go"]++          // оқыдық, қостық, кері жаздық

Жақша тілімдегідей, бірақ ішінде нөмір емес, кілт тұр. Ешқандай append керек емес: жаңа кілтке меншіктеу — сол қосу деген сөз.

Бағдарламаның басындағы литерал — сол істің қысқа жазуы: жұптар қос нүкте арқылы, әр жолдың соңында үтір, ең соңғысында да.

Кілт жоқ — бұл қате емес, нөл

views["музыка"] 0 басып шығарды, ондай тег жоқ бола тұра. Go бағдарламаны тоқтатқан да, шағымданған да жоқ: жоқ кілтті оқу — map жариялауында көрсетілген мән түрінің нөлдік мәнін қайтарады. int үшін ол 0, string үшін бос жол, bool үшін false.

Елестетіп көріңіз. Қоймадағы бос сөре. Сіз «музыка» сөресін сұрадыңыз — сізге «ондай жоқ» деген жоқ, бос сөрені көрсетті. Үстінде ештеңе жоқ, бірақ қате де жоқ.

Тапсырмадағы санауыш осыған сүйенеді: m[tag]++ бұрын болмаған тег үшін де жұмыс істейді — ол жай ғана нөлден бастайды.

Үтір-ok: кілт бар ма деп сұрау

Кейде айырма маңызды: нөл қаралым мен «тег жоқ» — екі бөлек нәрсе. Ондайда сөздіктен екі айнымалымен сұрайды:

n, ok := views["музыка"]   // 0, false

Екінші мән — кілт болса true, болмаса false. Бұл пішінді «үтір-ok» деп атайды, оны әлі талай кездестіресіз.

Аралау реті уәде етілмейді

Сөздік бойынша range барлық жұпты аралайды, бірақ реті әр жолы басқаша болуы мүмкін. Бұл салғырттық емес, шешім: Go аралауды әдейі әртүрлі жерден бастайды, ретке сүйенген код жазылмасын деп.

Өзіңіз тексеріңіз: сөздікті сұрыптамай аралап, бағдарламаны қатарынан он рет жіберіңіз — бірнеше түрлі рет көресіз.

Елестетіп көріңіз. Әр таратудың алдында араластырылатын карта дестесі. Карталар сол баяғы — бірақ олардың ретіне есеп құрған адам жаңылады.

Рет керек болса — кілттерді тілімге жинап, сұрыптаңыз, жоғарыдағы бағдарламадағыдай. slices.Sort стандартты кітапханадағы slices пакетінде тұр — аты өткен сабақтан таныс. Және make([]string, 0, len(views)) дегенге назар аударыңыз: ұзындығы нөл, сыйымдылығы алдын ала белгілі, бірде-бір көшу жоқ.

delete және len

len(views) — сөздікте қанша жұп бар. delete(views, "веб") — жұпты алып тастайды; ондай кілт болмаса, ештеңе болмайды, бұл да қате емес.

nil-сөздік: оқуға болады, жазуға болмайды

Мұнда сөздік тілімдей емес, басқаша ұстанады, айырманы бірден есте сақтаған жөн.

var m map[string]int
fmt.Println(m["go"])   // 0 — оқуға болады
m["go"] = 1            // panic: assignment to entry in nil map

Өткен сабақта var titles []string append-ті тыныш қабылдады. Ал var m map[string]int жазуды қабылдамайды: бағдарлама тоқтайды. Сөздікті жасау керек — make(map[string]int) немесе литералмен map[string]int{}.

Сабақ картасы

Сабақ картасы: кілт мәнді береді, ал жоқ кілт — нөл

Өз сөзіңізбен айтыңыз

Қарамай, дауыстап немесе қағазға жазып жауап беріңіз. Жауаптары — сабақтың соңында.

  1. views["музыка"] неге бағдарламаны тоқтатпай, нөл қайтарды? «Нөл қаралым» мен «ондай тег жоқ» дегенді қалай ажыратуға болады?
  2. Go сөздікті аралау ретін неге әдейі өзгертеді?
  3. var titles []string append-пен жұмыс істейді, ал var m map[string]int алғашқы жазудың өзінде құлайды. Айырмасы неде?

Тапсырма

Міндетті. count(tags []string) map[string]int функциясын жазыңыз — әр тег неше рет кездескенін санайды. Оны []string{"go", "веб", "go", "дала", "go", "веб"} үшін шақырып, нәтижесін кілттердің әліпби ретімен басып шығарыңыз — сөздіктің өзі сізге ондай рет бермейді.

Қалауыңызша.

  • has(m map[string]int, k string) bool — үтір-ok арқылы.
  • Кілтті delete арқылы өшіріп, len-ді бұрын және кейін басып шығарыңыз.
  • var m map[string]int ішіне жазып көріп, апат хабарын толық оқыңыз. panic хабарын оқу — ақауды табудың алғашқы қадамы.

Блогта қайда тұрады

Маршрут — сол сөздік: мекенжай бойынша өңдеушіні бәрін теріп шықпай табу. Тег бойынша қаралым санауышы — сөздік. Бір мақаланың үш тілі — ол да сөздік: kz, ru не en кілті бойынша өз мәтіні жатыр, өзіңіз оқып отырған сайт дәл солай құрылған. Құрылым туралы сабақта мән сан емес, тұтас мақала болады.

Өз блогыңызды жинаңыз. Мұнда соңғы екі сабақ тоғысады: тілім басты беттегі мақалалардың ретін ұстайды, ал сөздіктер мекенжай бойынша тақырып пен көлемді береді. Екеуінің бірі екіншісін алмастыра алмас еді, ал step-3 ішінде бұл жол-жолымен көрінеді.

Жауаптар

Жауаптарды көрсету
  1. Себебі Go-да жоқ кілтті оқу нөлдік мән береді — int үшін ол нөл. Ажырату үшін екі айнымалылы пішін бар: n, ok := views["музыка"], кілт болмаса ok false болады.
  2. Сөздік уәде етпейтін ретке ешкім сүйенбесін деп. Рет кездейсоқ тұрақты болып шықса, соған сүйенген бағдарламалар өсіп кетер еді — ішкі құрылым бір өзгергенде сынар еді. Рет керек болса, кілттерді тілімге жинап сұрыптаңыз.
  3. Бос тілім append-ке дайын: ол қоймасын өзі ашып, жаңа тілім қайтарады. Сөздікте append жоқ, жазу тікелей қоймаға барады — ал ол қойма әлі жасалмаған, сондықтан бағдарлама тоқтайды. Сөздікті make арқылы немесе литералмен жасайды.

Дереккөздер

Мәтінде қате не теру қатесі кездессе, бізге айтыңыз

Тапсырманы тексеру

Алдымен VS Code-та шешіп, іске қосыңыз — редактор қатені сол жерде көрсетеді. Дайын шешімді осында қойыңыз. Тексеретін — модель: ол қатені атап көрсетеді, бірақ дайын жауапты бермейді.

Тексеру үшін кіру керек. Кіру

Пікірлер (0)

Әзірге пікір жоқ. Бірінші болыңыз.