switch

Pemilihan tanpa fall-through bawaan dan bentuk switch tanpa ekspresi.

Daftar isi

Pernyataan switch memilih salah satu dari banyak cabang berdasarkan nilai sebuah ekspresi atau berdasarkan rangkaian kondisi. Topik ini membahas bentuk dasar switch, case dengan beberapa nilai, switch tanpa ekspresi, serta aturan bawaan yang menghentikan eksekusi sehingga tidak berlanjut ke case berikutnya. Semua contoh berupa program utuh dengan keluaran yang diambil langsung dari eksekusinya.

Bentuk dasar switch#

Pernyataan switch membandingkan nilai satu ekspresi dengan nilai-nilai yang tercantum pada tiap case, dari atas ke bawah. Cabang pertama yang cocok dieksekusi, sedangkan sisanya dilewati. Tidak ada break yang perlu ditulis di akhir badan case karena Go menghentikan eksekusinya secara otomatis. Badan case boleh memuat beberapa pernyataan sekaligus tanpa kurung kurawal tambahan, dan pemisahnya cukup baris baru. Kata kunci default menampung semua nilai yang tidak cocok dan boleh ditulis pada posisi mana pun. Ekspresi pada switch dievaluasi tepat satu kali, dan nilainya boleh berupa bilangan, string, atau tipe lain yang dapat dibandingkan.

Program berikut menentukan tugas piket berdasarkan nama hari. Kecocokan diperiksa satu per satu dari atas, dan nama hari Selasa berhenti pada case kedua.

go piket.go
package main

import "fmt"

func main() {
	hari := "Selasa"

	switch hari {
	case "Senin":
		fmt.Println("Piket menyapu lantai kelas")
	case "Selasa":
		fmt.Println("Piket membersihkan papan tulis")
	case "Rabu":
		fmt.Println("Piket membuang sampah")
	default:
		fmt.Println("Tidak ada jadwal piket")
	}
}
text Keluaran
Piket membersihkan papan tulis

Keluarannya hanya satu baris karena eksekusi berhenti tepat setelah badan case yang cocok selesai. Apabila variabel hari diganti menjadi “Kamis”, tidak ada case yang cocok sehingga cabang default yang dieksekusi. Program dijalankan dengan go run piket.go dari folder kerja tetap:

bash
# siapkan folder kerja untuk topik ini
mkdir -p /tmp/goalur/switch
cp piket.go /tmp/goalur/switch/
cd /tmp/goalur/switch

# periksa format sebelum menjalankan programnya
gofmt -l .

# jalankan programnya
go run piket.go
text Keluaran
Piket membersihkan papan tulis

switch tanpa ekspresi dan case dengan banyak nilai#

Bentuk switch tanpa ekspresi ditulis sebagai switch { ... } dan berperilaku seperti rangkaian if, else if yang tersusun sejajar. Setiap case memuat satu kondisi bertipe bool, dan cabang pertama yang bernilai true yang dieksekusi. Selain itu, satu case boleh memuat beberapa nilai yang dipisahkan koma, dan kecocokan terjadi bila salah satu nilai itu sama dengan ekspresi switch. Nilai pada case boleh berupa konstanta maupun ekspresi yang dihitung saat program berjalan, dan pencocokannya menggunakan perbandingan biasa. Kedua bentuk ini saling melengkapi, yaitu yang pertama untuk kondisi berjenjang dan yang kedua untuk pemilihan atas beberapa nilai yang setara.

Program berikut memuat dua switch. Yang pertama tanpa ekspresi untuk mengklasifikasikan suhu, sedangkan yang kedua menampung beberapa nilai jam dalam satu case.

go suhu.go
package main

import "fmt"

func main() {
	suhu := 28

	switch {
	case suhu <= 0:
		fmt.Println("Kategori suhu: beku")
	case suhu <= 20:
		fmt.Println("Kategori suhu: dingin")
	case suhu <= 30:
		fmt.Println("Kategori suhu: sedang")
	case suhu <= 40:
		fmt.Println("Kategori suhu: panas")
	default:
		fmt.Println("Kategori suhu: sangat panas")
	}

	jam := 7

	switch jam {
	case 6, 7, 8:
		fmt.Println("Jam berjalan: sibuk berangkat kerja")
	case 12, 13:
		fmt.Println("Jam berjalan: waktu istirahat")
	default:
		fmt.Println("Jam berjalan: normal")
	}
}
text Keluaran
Kategori suhu: sedang
Jam berjalan: sibuk berangkat kerja

Suhu 28 jatuh pada kondisi suhu <= 30 karena dua kondisi di atasnya terbukti salah terlebih dahulu. Urutan case pada bentuk tanpa ekspresi menentukan hasil. Apabila kondisi suhu <= 40 dipindah ke posisi paling atas, suhu 28 akan masuk kategori panas sebelum sempat mencapai kondisi yang lebih tepat.

switch juga menerima pernyataan init seperti if, yaitu pernyataan yang dieksekusi sekali sebelum ekspresi switch dievaluasi. Variabel yang dideklarasikan pada pernyataan init berlaku sampai akhir seluruh switch, sehingga pola lingkup yang sempit tetap terjaga:

go switch dengan pernyataan init
// tidak-dijalankan
switch n := len(nama); {
case n == 0:
	fmt.Println("nama masih kosong")
default:
	fmt.Println("nama sudah terisi")
}

Tidak ada fall-through bawaan#

Pada bahasa turunan C, badan case yang selesai melanjutkan eksekusi ke badan case berikutnya, perilaku yang dikenal sebagai fall-through. Go tidak menerapkan perilaku itu secara bawaan. Badan case yang selesai menghentikan seluruh switch, sehingga tidak ada case lain yang tersentuh. Kata kunci fallthrough tetap tersedia untuk meneruskan eksekusi secara eksplisit, tetapi pemakaiannya langka karena menyembunyikan alur dari pembaca kode. Pernyataan fallthrough hanya boleh menjadi pernyataan terakhir pada badan case.

Program berikut menyisipkan fallthrough di akhir badan case pertama untuk memperlihatkan efeknya:

go fallthrough.go
package main

import "fmt"

func main() {
	level := 1

	switch level {
	case 1:
		fmt.Println("Level 1: langkah dasar")
		fallthrough
	case 2:
		fmt.Println("Level 2: pemanasan")
	case 3:
		fmt.Println("Level 3: latihan inti")
	default:
		fmt.Println("Level di luar jangkauan")
	}
}
text Keluaran
Level 1: langkah dasar
Level 2: pemanasan

Meskipun level bernilai 1 dan tidak cocok dengan case 2, baris Level 2 tetap tercetak. fallthrough memaksa eksekusi masuk ke badan case berikutnya tanpa memeriksa kecocokannya. Baris Level 3 tidak tercetak karena badan case 2 tidak memuat fallthrough, sehingga switch berhenti di sana.

Kesalahan umum#

Tiga kesalahan berikut lazim ditemui ketika switch mulai dipakai.

  1. Mengira eksekusi berlanjut ke case berikutnya. Logika yang ditulis pada dua case berurutan dengan harapan keduanya dieksekusi hanya akan menjalankan case pertama yang cocok. Perbaikannya adalah memanggil fungsi yang sama dari beberapa case, atau menulis fallthrough apabila penerusan eksekusi memang dimaksudkan dan tata alurnya tetap mudah diikuti.

  2. Dua case dengan nilai konstanta yang sama. Konstanta yang ganda membuat pemeriksaan tidak bermakna, sehingga compiler menolaknya saat kompilasi. Pesan errornya menyebut nilai yang ganda beserta letak case sebelumnya:

go Dua case dengan konstanta yang sama
// tidak-dijalankan
switch jam {
case 7:
	fmt.Println("pagi")
case 7: // error kompilasi: duplicate case 7 (constant of type int) in expression switch
	fmt.Println("pagi juga")
}
  1. Tipe case yang tidak cocok dengan ekspresi switch. Pada switch suhu yang tipenya int, case tidak boleh berupa kondisi bool seperti suhu > 30. Compiler menolaknya dengan pesan cannot convert suhu > 30 (untyped bool value) to type int. Bentuk yang tepat untuk kondisi semacam itu adalah switch tanpa ekspresi, sehingga setiap case memuat kondisi bool yang utuh.

Ringkasan#

  • switch membandingkan satu ekspresi dengan nilai-nilai case dari atas ke bawah dan mengeksekusi cabang pertama yang cocok.
  • Tidak ada break yang perlu ditulis karena badan case berhenti otomatis, sedangkan default menampung nilai yang tidak cocok.
  • Switch tanpa ekspresi memeriksa kondisi bool berurutan, dan satu case boleh memuat beberapa nilai yang dipisahkan koma.
  • Lanjutan antarbadan case hanya terjadi melalui fallthrough yang ditulis eksplisit sebagai pernyataan terakhir.

Referensi#