Array, slice, dan map sama-sama menampung banyak nilai, tetapi ketiganya dirancang untuk masalah yang berbeda. Memilih struktur yang tepat menentukan kecepatan program, keringkasan kode, dan kebebasan dari bug halus seperti aliasing. Kabar baiknya: setelah menempuh sembilan chapter sebelumnya, kita sudah punya semua pengetahuan untuk mengambil keputusan itu secara sadar. Chapter penutup ini merangkum ketiga struktur dalam satu tabel keputusan lalu mempraktikkan tiga skenario pilihan yang paling sering dijumpai.

Tabel Perbandingan #

AspekArraySliceMap
UkuranTetap, ditentukan saat kompilasiDinamis, tumbuh lewat appendDinamis, tumbuh per key baru
Cara aksesa[i] lewat indekss[i] lewat indeksm[k] lewat key comparable
Ordo aksesKonstanKonstanRata-rata konstan
Iterasi terurutYa, dari indeks 0Ya, dari indeks 0Tidak; key harus diurutkan dulu
Urutan penyimpananTerjagaTerjagaTidak terjaga
Salinan saat assignmentSeluruh isi disalinHanya header slice yang disalinHanya penunjuk map yang disalin
Use case khasBuffer tetap, RGB, hashDaftar berurutan, riwayat, antreanKamus, indeks, penghitungan frekuensi

Tiga baris teratas adalah kriteria utama: tanyakan apakah ukuran data tetap, apakah akses dilakukan lewat posisi atau lewat key, dan apakah urutan perlu terjaga. Jawaban atas ketiganya hampir selalu langsung menunjuk satu struktur.

Daftar Berurutan: Pilih Slice #

Ketika urutan penulisan data bermakna — langkah proses, riwayat pesanan, antrean tugas — slice adalah pilihan default. Urutan elemen slice terjaga sejak awal, indeks memungkinkan akses konstan ke posisi mana pun, dan append menampung pertumbuhan data tanpa biaya desain. Konsekuensinya: mencari satu nilai tertentu di slice memeriksa elemen satu per satu, sehingga makin panjang slice makin lama pencarian. Bila pencarian seperti itu menjadi frekuensi utama program, itu pertanda struktur yang dibutuhkan bukan slice.

Lookup Berdasarkan Key: Pilih Map #

Ketika data diakses lewat nama, kode, atau identitas lain — bukan posisi — map menjawab langsung: kodePos["Bandung"] menemukan nilai tanpa memeriksa entri lain. Map juga unggul saat menghitung frekuensi kemunculan, misalnya frekuensi[kata]++ yang bekerja meski key belum pernah ada. Imbalannya, urutan penyimpanan tidak dijaga dan iterasi harus diurutkan secara eksplisit memakai slices.Sorted(maps.Keys(m)) bila output perlu stabil.

Ukuran Selalu Tetap: Pilih Array #

Array layak dipilih ketika ukuran data memang tidak mungkin berubah: warna piksel selalu tiga byte, hash SHA-256 selalu 32 byte, buffer I/O berukuran tetap. Nilai yang disalin utuh saat assignment juga menjadi keuntungan tersendiri: array bebas dari bug aliasing yang menghantui slice. Untuk semua kasus lain — hampir seluruh kode sehari-hari — slice dan map lebih luwes.

Program Utuh #

Berkas pilihan-demo.go menerapkan ketiga keputusan dalam satu program. Jalankan dengan go run pilihan-demo.go dari direktori chapter:

go
package main

import (
	"fmt"
	"maps"
	"slices"
)

func main() {
	// Daftar berurutan: urutan penulisan harus terjaga, pakai slice.
	urutan := []string{"masuk", "pilih barang", "checkout"}
	fmt.Println("urutan:", urutan)

	// Cari nilai di slice: periksa elemen satu per satu.
	target := "checkout"
	ditemukan := false
	for _, langkah := range urutan {
		if langkah == target {
			ditemukan = true
			break
		}
	}
	fmt.Println("checkout ditemukan:", ditemukan)

	// Lookup berdasarkan key: akses langsung, pakai map.
	kodePos := map[string]int{
		"Jakarta Pusat": 10110,
		"Bandung":       40111,
		"Surabaya":      60119,
	}
	if kp, ok := kodePos["Bandung"]; ok {
		fmt.Println("kode pos Bandung:", kp)
	}

	// Iterasi map yang terurut memakai slices dan maps.
	for _, kota := range slices.Sorted(maps.Keys(kodePos)) {
		fmt.Printf("%s: %d\n", kota, kodePos[kota])
	}

	// Data berukuran tetap: warna RGB selalu tiga byte, pakai array.
	piksel := [3]byte{255, 128, 0}
	fmt.Println("piksel:", piksel)
}

Output yang Dihasilkan:

text
urutan: [masuk pilih barang checkout]
checkout ditemukan: true
kode pos Bandung: 40111
Bandung: 40111
Jakarta Pusat: 10110
Surabaya: 60119
piksel: [255 128 0]

Mari kita telaah baris demi baris program di atas:

  1. Baris 11 (urutan := []string{...}): langkah proses disimpan sebagai slice karena urutan masuk-pilih-checkout adalah bagian dari makna data.
  2. Baris 14–22 (loop pencarian): menemukan "checkout" menuntut pemeriksaan elemen satu per satu dengan break — karakteristik pencarian di slice yang perlu dipertimbangkan saat memilih struktur.
  3. Baris 25–30 (map kodePos): pencarian kode pos dilakukan lewat key; comma-ok memastikan key ada sebelum nilainya dipakai.
  4. Baris 33–35 (slices.Sorted(maps.Keys(kodePos))): iterasi terurut menghasilkan output Bandung, Jakarta Pusat, Surabaya yang stabil di setiap eksekusi.
  5. Baris 38 (piksel := [3]byte{255, 128, 0}): warna piksel berukuran pasti tiga byte sehingga array [3]byte pas — tidak ada kemungkinan tumbuh yang justru tidak diinginkan.

Ketiga struktur ini akan terus muncul di sepanjang perjalanan kita, mulai dari pengolahan string di Section String dan Text Processing hingga struktur data concurrency. Dengan tabel keputusan di atas, setiap kali mendeklarasikan []T atau map[K]V, kita melakukannya karena sadar itu pilihan paling tepat — bukan sekadar kebiasaan.

Referensi #

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

pilihan-demo.go

Unduh berkas
go
package main

import (
	"fmt"
	"maps"
	"slices"
)

func main() {
	// Daftar berurutan: urutan penulisan harus terjaga, pakai slice.
	urutan := []string{"masuk", "pilih barang", "checkout"}
	fmt.Println("urutan:", urutan)

	// Cari nilai di slice: periksa elemen satu per satu.
	target := "checkout"
	ditemukan := false
	for _, langkah := range urutan {
		if langkah == target {
			ditemukan = true
			break
		}
	}
	fmt.Println("checkout ditemukan:", ditemukan)

	// Lookup berdasarkan key: akses langsung, pakai map.
	kodePos := map[string]int{
		"Jakarta Pusat": 10110,
		"Bandung":       40111,
		"Surabaya":      60119,
	}
	if kp, ok := kodePos["Bandung"]; ok {
		fmt.Println("kode pos Bandung:", kp)
	}

	// Iterasi map yang terurut memakai slices dan maps.
	for _, kota := range slices.Sorted(maps.Keys(kodePos)) {
		fmt.Printf("%s: %d\n", kota, kodePos[kota])
	}

	// Data berukuran tetap: warna RGB selalu tiga byte, pakai array.
	piksel := [3]byte{255, 128, 0}
	fmt.Println("piksel:", piksel)
}