if dengan Pernyataan init

Kondisi dengan lingkup variabel terbatas dan ketiadaan operator ternary.

Daftar isi

Pernyataan if mengeksekusi satu blok kode hanya apabila kondisi yang menyertainya terpenuhi. Topik ini membahas bentuk dasar if, else if, dan else, pernyataan init beserta lingkup variabel yang dideklarasikannya, serta alasan Go tidak menyediakan operator ternary, yaitu pemilihan nilai bersyarat dalam satu ekspresi. Semua contoh berupa program utuh yang dapat dijalankan, dan setiap keluaran diambil langsung dari eksekusinya.

Bentuk dasar if dan else#

Pernyataan if mengevaluasi sebuah kondisi bertipe bool, yaitu ekspresi yang hanya bernilai true atau false. Tanda kurung tidak dipakai untuk mengapit kondisi, sedangkan kurung kurawal pembatas bloknya wajib ditulis. Apabila ada lebih dari dua kemungkinan, cabang else if dan else menyusulnya. Eksekusi memilih cabang pertama yang kondisinya terpenuhi, lalu melewati seluruh cabang lainnya. Tanda kurung pengapit kondisi masih sah menurut spesifikasi bahasa, tetapi konvensi penulisan Go melepasnya.

Program berikut mengklasifikasikan nilai ujian ke dalam kategori huruf. Kondisi diperiksa dari atas ke bawah, sehingga urutan penulisannya menentukan hasil. Apabila kondisi yang lebih longgar ditulis lebih dahulu, nilai tinggi akan tertangkap oleh cabang kondisi longgar itu sebelum sempat mencapai cabang yang lebih sempit. Keluaran dicetak menggunakan fmt.Printf dengan verb %d, yaitu penanda yang digantikan oleh sebuah bilangan bulat.

go kategori.go
package main

import "fmt"

func main() {
	nilai := 86

	if nilai >= 80 {
		fmt.Printf("Nilai %d masuk kategori A\n", nilai)
	} else if nilai >= 70 {
		fmt.Printf("Nilai %d masuk kategori B\n", nilai)
	} else if nilai >= 60 {
		fmt.Printf("Nilai %d masuk kategori C\n", nilai)
	} else {
		fmt.Printf("Nilai %d masuk kategori D\n", nilai)
	}
}
text Keluaran
Nilai 86 masuk kategori A

Nilai 86 memenuhi kondisi pertama, sehingga blok kategori A yang dieksekusi dan tiga cabang di bawahnya tidak diperiksa lagi. Program disimpan sebagai kategori.go dan dijalankan dengan alat go run dari folder kerja tetap:

bash
# siapkan folder kerja untuk topik ini
mkdir -p /tmp/goalur/if-dengan-init
cp kategori.go /tmp/goalur/if-dengan-init/
cd /tmp/goalur/if-dengan-init

# periksa format sebelum menjalankan programnya
gofmt -l .

# jalankan programnya
go run kategori.go
text Keluaran
Nilai 86 masuk kategori A

Pernyataan init dan lingkup variabelnya#

Bentuk lengkap if memuat pernyataan init, yaitu pernyataan sederhana yang dieksekusi sekali sebelum kondisi diperiksa. Bentuk penulisannya if init; kondisi, dengan titik koma sebagai pemisah keduanya. Tempat paling umum bagi pernyataan init adalah deklarasi variabel yang hasilnya hanya dipakai untuk pengambilan keputusan. Variabel seperti itu berlaku sampai akhir rantai if, else if, dan else, lalu tidak dapat digunakan lagi di luar bloknya.

Program berikut menghitung rata-rata tiga nilai ujian di dalam pernyataan init, lalu membandingkan rata-rata tersebut dengan batas minimal. Perhitungan menggunakan pembagian bilangan bulat, sehingga 245 dibagi 3 menghasilkan 81 dan bukan 81,67 karena bagian desimalnya dibuang. Bentuk ini juga memisahkan penghitungan dari keputusan, sehingga baris kondisinya tetap pendek dan mudah dibaca.

go batas.go
package main

import "fmt"

func main() {
	a, b, c := 70, 85, 90

	if rata := (a + b + c) / 3; rata >= 75 {
		fmt.Printf("Rata-rata %d memenuhi batas minimal\n", rata)
	} else {
		fmt.Printf("Rata-rata %d di bawah batas minimal\n", rata)
	}
}
text Keluaran
Rata-rata 81 memenuhi batas minimal

Lingkup yang sempit itu disengaja. Variabel rata berhenti berlaku pada akhir rantai, sehingga tidak ada risiko nama itu terpakai ulang tanpa sengaja di bagian program lain. Apabila nama itu dipanggil setelah rantai berakhir, compiler, yaitu program yang menerjemahkan kode sumber menjadi biner, menolaknya saat kompilasi. Fragmen berikut memperlihatkan penolakan tersebut.

go Variabel init tidak terlihat di luar rantai if
// tidak-dijalankan
if rata := (a + b + c) / 3; rata >= 75 {
	fmt.Println("memenuhi batas minimal")
}
fmt.Println(rata) // error kompilasi: undefined: rata

Pesan undefined: rata menyatakan bahwa nama itu tidak dikenal pada posisi pemanggilannya.

Menggantikan operator ternary#

Banyak bahasa lain menyediakan operator ternary, yaitu ekspresi bersyarat dengan tiga operan yang memilih salah satu dari dua nilai dalam satu baris, misalnya a < b ? a : b. Go tidak menyediakannya, dan baris yang meniru pola itu ditolak compiler saat kompilasi:

go Pola ternary yang tidak dikenal Go
// tidak-dijalankan
min := a < b ? a : b // error kompilasi: invalid character U+003F '?'

Penggantinya adalah deklarasi nilai awal yang diperbaiki oleh if biasa. Pola ini sedikit lebih panjang, tetapi setiap langkahnya eksplisit dan mudah dibaca:

go minimum.go
package main

import "fmt"

func main() {
	a, b := 12, 7

	min := a
	if b < a {
		min = b
	}

	fmt.Printf("Nilai terkecil dari %d dan %d adalah %d\n", a, b, min)
}
text Keluaran
Nilai terkecil dari 12 dan 7 adalah 7

Alasan ketiadaan operator ternary tercantum dalam FAQ resmi Go. Operator ternary sering digunakan untuk menyusun ekspresi yang padat namun sulit dibaca, sedangkan rancangan Go mengutamakan kejelasan daripada kepadatan. Karena itu, pemilihan nilai bersyarat dituliskan dengan pernyataan if dan else.

Kesalahan umum#

Tiga kesalahan berikut paling sering muncul ketika if baru dipraktikkan.

  1. else ditulis di baris baru. Go menerapkan automatic semicolon insertion, yaitu penyisipan titik koma otomatis setelah token tertentu di akhir baris, termasuk setelah kurung kurawal penutup. Baris } dan else yang terpisah dianggap dua pernyataan berbeda, sehingga compiler menolaknya. Perbaikannya adalah menulis } else { pada baris yang sama:
go else yang dipisahkan dari kurung kurawal penutup
// tidak-dijalankan
if nilai >= 80 {
	fmt.Println("kategori A")
}
else { // error kompilasi: unexpected keyword else, expected }
	fmt.Println("kategori lain")
}
  1. Kondisi tidak bertipe bool. Kondisi if wajib menghasilkan nilai bool, sehingga variabel bilangan yang ditulis langsung sebagai kondisi ditolak compiler dengan pesan non-boolean condition in if statement. Perbaikannya adalah menulis perbandingan yang lengkap, misalnya if nilai >= 80:
go Kondisi yang tidak bertipe bool
// tidak-dijalankan
if nilai { // error kompilasi: non-boolean condition in if statement
	fmt.Println("terpenuhi")
}
  1. Variabel init dipanggil setelah rantai berakhir. Lingkup variabel pernyataan init berhenti di akhir rantai, dan pemanggilan di luarnya memunculkan pesan undefined: rata seperti pada bagian pernyataan init. Perbaikannya adalah memindahkan deklarasi variabel ke atas rantai apabila nilainya memang perlu digunakan lagi setelahnya.

Ringkasan#

  • if mengeksekusi bloknya hanya bila kondisi bertipe bool terpenuhi, tanpa tanda kurung pengapit dan dengan kurung kurawal yang wajib.
  • Pernyataan init pada bentuk if init; kondisi dieksekusi sekali sebelum kondisi, dan variabelnya hanya berlaku sampai akhir rantai if, else if, dan else.
  • Go tidak memiliki operator ternary, sehingga pemilihan nilai bersyarat ditulis dengan deklarasi nilai awal dan if, else.
  • else wajib menyatu dengan baris kurung kurawal penutup cabang sebelumnya karena penyisipan titik koma otomatis.

Referensi#