Golang Dasar: Dari Nol hingga CLI Production-Ready3/10

Bab 3 dari 10

Alur Kontrol di Go

Tujuan Pembelajaran

Setelah bab ini, Anda mampu:

  • membuat percabangan dengan if dan switch;
  • menulis berbagai bentuk perulangan for;
  • mengiterasi koleksi dengan range;
  • memakai break dan continue secara terukur;
  • menghindari jebakan scope dan kondisi batas.

1. if, else if, dan Scope

Kondisi if harus bernilai bool; Go tidak menganggap 0, string kosong, atau nil sebagai false secara implisit. Tanda kurung tidak diperlukan, sedangkan kurung kurawal wajib.

Code
package main

import "fmt"

func kategori(nilai int) string {
	if nilai >= 85 {
		return "A"
	} else if nilai >= 70 {
		return "B"
	}
	return "C"
}

func main() {
	fmt.Println(kategori(78))
}

Karena cabang pertama sudah return, else sebenarnya dapat dihilangkan untuk mengurangi indentasi.

if dapat memiliki pernyataan pendek yang scopenya terbatas pada seluruh rantai if:

Code
package main

import (
	"fmt"
	"strconv"
)

func main() {
	if n, err := strconv.Atoi("42"); err != nil {
		fmt.Println("input tidak valid")
	} else {
		fmt.Println(n * 2)
	}
}

2. switch

switch Go berhenti otomatis setelah satu kasus cocok; tidak memerlukan break. Beberapa nilai dapat berada dalam satu case.

Code
package main

import "fmt"

func jenisHari(hari string) string {
	switch hari {
	case "Sabtu", "Minggu":
		return "akhir pekan"
	case "Senin", "Selasa", "Rabu", "Kamis", "Jumat":
		return "hari kerja"
	default:
		return "tidak dikenal"
	}
}

func main() {
	fmt.Println(jenisHari("Sabtu"))
}

Switch tanpa ekspresi setara dengan switch true dan berguna untuk kondisi berurutan:

Code
func suhuLabel(c float64) string {
	switch {
	case c < 0:
		return "beku"
	case c < 30:
		return "sedang"
	default:
		return "panas"
	}
}

Urutan kasus penting: kasus pertama yang benar dipilih. fallthrough ada, tetapi jarang dibutuhkan karena mengeksekusi kasus berikutnya tanpa memeriksa kondisinya.

3. Satu Kata Kunci Perulangan: for

Go memakai for untuk seluruh bentuk perulangan.

Code
package main

import "fmt"

func main() {
	for i := 0; i < 3; i++ {
		fmt.Println(i)
	}

	n := 3
	for n > 0 {
		fmt.Println(n)
		n--
	}
}

Perulangan tanpa kondisi berjalan sampai dihentikan:

Code
for {
	// hentikan dengan break, return, atau kondisi eksternal
	break
}

Aliran keputusan loop:

Memuat diagram…

4. Iterasi dengan range

range menghasilkan pasangan indeks/nilai untuk slice dan array, serta key/value untuk map.

Code
package main

import "fmt"

func main() {
	nilai := []int{80, 90, 75}
	total := 0
	for i, n := range nilai {
		fmt.Printf("nilai[%d]=%d\n", i, n)
		total += n
	}
	fmt.Println("total:", total)
}

Gunakan blank identifier untuk hasil yang tidak dibutuhkan:

Code
for _, n := range nilai {
	fmt.Println(n)
}

Urutan iterasi map sengaja tidak ditentukan. Jangan mengandalkannya untuk output stabil; kumpulkan dan urutkan key terlebih dahulu jika urutan diperlukan.

Pada string, range menghasilkan indeks byte dan rune yang didekode. Pada slice nilai struct, variabel nilai adalah salinan; ubah elemen melalui indeks bila mutasi diperlukan:

Code
for i := range nilai {
	nilai[i] *= 2
}

5. break, continue, dan Label

continue melanjutkan iterasi berikutnya; break keluar dari loop atau switch terdekat.

Code
package main

import "fmt"

func main() {
	for n := 1; n <= 10; n++ {
		if n%2 != 0 {
			continue
		}
		if n > 6 {
			break
		}
		fmt.Println(n)
	}
}

Label berguna untuk keluar dari loop bersarang, tetapi sering kali fungsi kecil dan return lebih mudah dibaca:

Code
package main

import "fmt"

func main() {
Luar:
	for baris := 0; baris < 3; baris++ {
		for kolom := 0; kolom < 3; kolom++ {
			if baris == 1 && kolom == 1 {
				break Luar
			}
			fmt.Println(baris, kolom)
		}
	}
}

Kesalahan Umum

  • Menulis kondisi non-boolean. Gunakan perbandingan eksplisit, misalnya n != 0.
  • Menambah break rutin pada setiap case. Switch Go tidak jatuh ke kasus berikutnya secara default.
  • Loop tak berujung karena lupa memperbarui kondisi. Pastikan setiap jalur memajukan state atau berhenti.
  • Mengandalkan urutan map. Urutkan key jika hasil harus deterministik.
  • Memodifikasi salinan dari range. Gunakan indeks untuk mengubah elemen slice.
  • Off-by-one. Untuk panjang len(data), indeks valid adalah 0 sampai len(data)-1; kondisi lazim adalah i < len(data).
  • Scope variabel terlalu sempit. Nilai dari short statement if tidak tersedia setelah rantai tersebut.

Latihan

  1. Cetak angka 1–100; ganti kelipatan 3 dengan Fizz, 5 dengan Buzz, dan keduanya dengan FizzBuzz.
  2. Buat fungsi yang mengklasifikasikan usia menggunakan switch tanpa ekspresi.
  3. Hitung nilai minimum, maksimum, dan rata-rata sebuah slice tanpa package tambahan.
  4. Iterasi string beraksara multibyte dan tampilkan indeks byte serta rune.
  5. Buat pencarian pada matriks yang berhenti ketika target ditemukan; implementasikan sekali dengan label dan sekali dengan fungsi yang mengembalikan hasil.

Rangkuman

if menangani keputusan boolean, sedangkan switch menyederhanakan banyak cabang dan berhenti otomatis. Semua perulangan memakai for; range memberi iterasi idiomatis atas koleksi dan string. Gunakan break, continue, dan label hanya ketika membuat alur lebih jelas, serta perhatikan scope, batas indeks, salinan nilai, dan urutan map yang tidak dijamin.