Map menyimpan pasangan kunci-nilai, tetapi operasi sehari-hari di sekitarnya — mengkloning, menyalin, menyaring, membandingkan, sampai mengiterasi secara terurut — lama ditulis manual dengan loop sendiri. Sejak Go 1.21, package maps menyediakan seluruh utilitas tersebut secara generik untuk map tipe apa pun. Chapter ini membedah fungsi intinya sekaligus menjelaskan perilaku iterasi map yang harus diketahui setiap penulis Go.
Keys dan Values sebagai Iterator #
Sejak Go 1.23, maps.Keys dan maps.Values tidak lagi mengembalikan slice. Keduanya mengembalikan iterator bertipe iter.Seq yang dapat dipakai langsung pada for range, atau diteruskan ke fungsi penerima iterator seperti slices.Collect dan slices.Sorted. Untuk mengiterasi map dengan urutan kunci yang pasti, idiomnya menggabungkan keduanya:
for _, k := range slices.Sorted(maps.Keys(stok)) {
fmt.Println(k, stok[k])
}maps.Keys(stok) menghasilkan iterator kunci, slices.Sorted mengurutkannya menjadi slice baru, dan loop membaca nilai lewat stok[k]. Tanpa pengurutan, loop for k := range stok tetap sah — hanya saja urutannya tidak bisa diandalkan. slices.Collect(maps.Keys(m)) mengumpulkan kunci menjadi slice tanpa mengurutkan, berguna bila urutan tidak penting.
Iterator nilai dibaca dengan satu variabel loop karena maps.Values mengalirkan nilai saja:
for v := range maps.Values(stok) {
fmt.Println(v)Clone dan Copy #
maps.Clone menyalin seluruh map menjadi map baru dengan tipe sama. Penambahan atau penghapusan pada salinan tidak menyentuh map asli, sehingga fungsi yang perlu memodifikasi data dapat bekerja pada salinan. maps.Copy memindahkan pasangan kunci-nilai dari map sumber ke map target: pasangan yang kuncinya sudah ada di target akan ditimpa nilainya, kunci yang belum ada akan ditambahkan.
Sebutan singkat: maps.Collect membangun map baru dari iterator pasangan, dan maps.Insert mengisi map dari iterator pasangan — keduanya berguna saat data berpindah antar bentuk iterator dan map.
DeleteFunc untuk Menyaring #
maps.DeleteFunc menghapus setiap pasangan yang membuat predikat bernilai true. Predikatnya menerima kunci dan nilai, jadi penyaringan bisa mempertimbangkan keduanya — misalnya menghapus item stok di bawah batas minimum. Fungsi memodifikasi map di tempat dan tidak mengembalikan map baru.
Equal dan EqualFunc #
maps.Equal membandingkan dua map secara pasangan: sama-sama tidak punya kunci lebih, dan setiap kunci yang sama nilainya harus sama. Perbandingan dengan operator == pada dua variabel map hanya memeriksa apakah keduanya merujuk map yang sama, bukan isinya. maps.EqualFunc memakai fungsi pembanding nilai sendiri, berguna untuk nilai yang tidak comparable seperti slice.
Program Utuh #
Berkas maps-demo.go merangkai seluruh materi chapter:
package main
import (
"fmt"
"maps"
"slices"
)
func main() {
stok := map[string]int{
"pensil": 24,
"buku": 12,
"penghapus": 7,
}
// Urutan iterasi map diacak Go; urutkan kuncinya agar output selalu sama.
for _, nama := range slices.Sorted(maps.Keys(stok)) {
fmt.Printf("%-9s : %d\n", nama, stok[nama])
}
// Clone menyalin seluruh map menjadi map baru yang mandiri.
salinan := maps.Clone(stok)
salinan["spidol"] = 3
fmt.Println("kunci :", len(salinan), "disalin,", len(stok), "asli")
// Copy memindahkan pasangan kunci-nilai dari sumber ke target.
target := map[string]int{"buku": 99}
maps.Copy(target, stok)
fmt.Println("copy :", target)
// DeleteFunc menghapus pasangan yang memenuhi predikat.
sisa := maps.Clone(stok)
maps.DeleteFunc(sisa, func(k string, v int) bool {
return v < 10
})
fmt.Println("sisa :", sisa)
// Equal membandingkan isi dua map pasangan demi pasangan.
fmt.Println("equal :", maps.Equal(stok, maps.Clone(stok)), maps.Equal(stok, sisa))
// Values mengembalikan iterator nilai (satu variabel loop) untuk dijumlahkan.
total := 0
for v := range maps.Values(stok) {
total += v
}
fmt.Println("total :", total)
}Jalankan program dari folder chapter:
go run maps-demo.goOutput yang Dihasilkan:
buku : 12
penghapus : 7
pensil : 24
kunci : 4 disalin, 3 asli
copy : map[buku:12 penghapus:7 pensil:24]
sisa : map[buku:12 pensil:24]
equal : true false
total : 43Mari kita telaah baris demi baris program di atas:
- Baris 4-6: tiga package diimpor —
fmtuntuk mencetak,mapsuntuk utilitas map, danslicesuntukSorted. - Baris 10-14: map
stokdideklarasikan dengan tiga pasangan kunci-nilai. - Baris 17-19: kunci diurutkan lewat
slices.Sorted(maps.Keys(stok))sehingga tiga baris pertama output selalubuku,penghapus, lalupensil. - Baris 22-24:
Clonemembuat salinan; penambahanspidolhanya menaikkan jumlah kunci salinan menjadi 4. - Baris 27-29:
Copymenimpa nilaibukudi target dengan nilai dari sumber dan menambahkan dua kunci lain. - Baris 32-36:
DeleteFuncmenghapus pasangan dengan nilai di bawah 10, menyisakanbukudanpensil. - Baris 39:
Equalmembandingkanstokdengan klonnya (sama) dan dengansisa(berbeda). - Baris 42-46: iterator
maps.Valuesdijumlahkan menjadi total 43 lewat satu variabel loop.
Referensi #
- Dokumentasi package maps — seluruh fungsi utilitas map generik.
- Dokumentasi package slices
—
SorteddanCollectsebagai konsumen iterator. - Dokumentasi package iter
— tipe
iter.Seqyang dikembalikanKeysdanValues.
Map dan slice kini bisa diolah dengan utilitas standar yang ringkas. Perhatian kita beralih ke jejak eksekusi program: dua chapter berikutnya membahas pencatatan kejadian dengan log klasik dan log/slog terstruktur.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
maps-demo.go
Unduh berkaspackage main
import (
"fmt"
"maps"
"slices"
)
func main() {
stok := map[string]int{
"pensil": 24,
"buku": 12,
"penghapus": 7,
}
// Urutan iterasi map diacak Go; urutkan kuncinya agar output selalu sama.
for _, nama := range slices.Sorted(maps.Keys(stok)) {
fmt.Printf("%-9s : %d\n", nama, stok[nama])
}
// Clone menyalin seluruh map menjadi map baru yang mandiri.
salinan := maps.Clone(stok)
salinan["spidol"] = 3
fmt.Println("kunci :", len(salinan), "disalin,", len(stok), "asli")
// Copy memindahkan pasangan kunci-nilai dari sumber ke target.
target := map[string]int{"buku": 99}
maps.Copy(target, stok)
fmt.Println("copy :", target)
// DeleteFunc menghapus pasangan yang memenuhi predikat.
sisa := maps.Clone(stok)
maps.DeleteFunc(sisa, func(k string, v int) bool {
return v < 10
})
fmt.Println("sisa :", sisa)
// Equal membandingkan isi dua map pasangan demi pasangan.
fmt.Println("equal :", maps.Equal(stok, maps.Clone(stok)), maps.Equal(stok, sisa))
// Values mengembalikan iterator nilai (satu variabel loop) untuk dijumlahkan.
total := 0
for v := range maps.Values(stok) {
total += v
}
fmt.Println("total :", total)
}