Map — Go

Map di Go Map adalah struktur data key-value seperti dictionary di Python atau object di JavaScript. Membuat Map // Literal umur := map[string]int{ "Budi": 25,

Map di Go

Map adalah struktur data key-value seperti dictionary di Python atau object di JavaScript.

Membuat Map

// Literal
umur := map[string]int{
    "Budi":  25,
    "Sari":  30,
    "Andi":  22,
}

// Menggunakan make
skor := make(map[string]int)

Operasi Map

m := map[string]int{"a": 1, "b": 2}

// Akses
fmt.Println(m["a"]) // 1

// Set / Update
m["c"] = 3

// Delete
delete(m, "b")

// Cek apakah key ada
val, ok := m["a"]
if ok {
    fmt.Println("Ada:", val)
} else {
    fmt.Println("Tidak ada")
}

Iterasi Map

for key, value := range m {
    fmt.Printf("%s: %d\n", key, value)
}

Panjang Map

fmt.Println(len(m)) // jumlah key-value pairs

⚠️ Map Go TIDAK Thread-Safe

Ini salah satu jebakan terbesar dalam Go concurrency. Map bawaan Go tidak aman diakses dari banyak goroutine secara bersamaan — runtime Go akan crash program-mu (fatal error: concurrent map writes) jika mendeteksi read+write simultan.

// BAHAYA — race condition, program bisa crash
m := make(map[string]int)
for i := 0; i < 100; i++ {
    go func(i int) {
        m[fmt.Sprintf("k%d", i)] = i // panic!
    }(i)
}

Solusi 1: sync.Mutex — paling umum dan fleksibel:

var mu sync.Mutex
m := make(map[string]int)

go func() {
    mu.Lock()
    defer mu.Unlock()
    m["key"] = 42
}()

Solusi 2: sync.RWMutex — cocok kalau read jauh lebih sering dari write (banyak reader bisa lock bersamaan):

var mu sync.RWMutex
mu.RLock()            // baca
val := m["key"]
mu.RUnlock()

mu.Lock()             // tulis
m["key"] = 100
mu.Unlock()

Solusi 3: sync.Map — map bawaan yang thread-safe. Tapi hanya optimal untuk pola "write-once, read-many" (cache) atau key yang tumpang tindih jarang. Untuk kasus umum, Mutex + map lebih cepat.

Cara deteksi race condition: jalankan program dengan go run -race main.go. Race detector akan melaporkan akses tidak sinkron yang bisa jadi bug.

Yang akan kamu pelajari