Banyak keputusan dalam program bergantung pada nilai yang harus dihitung lebih dulu: hasil konversi teks menjadi angka, hasil pencarian data, atau status sebuah operasi. Tanpa fitur khusus, kita terpaksa mendeklarasikan variabel sementara di luar if, lalu variabel tersebut menetap di fungsi padahal hanya dipakai sekali. Go mengatasinya dengan bentuk if yang memiliki initializer: satu statement singkat yang dijalankan tepat sebelum kondisi dievaluasi. Pada chapter ini kita memakai pola tersebut untuk konversi angka dengan strconv.Atoi dan memahami ruang lingkup variabelnya yang sengaja dibuat sempit.
Masalah Variabel Sementara #
Mari kita lihat versi tanpa initializer lebih dulu. Kode berikut mengubah teks menjadi angka, memeriksa galatnya, lalu memakai hasilnya:
nilai, err := strconv.Atoi(input)
if err != nil {
fmt.Println("Konversi gagal:", err)
} else {
fmt.Println("Angka:", nilai)
}Kode di atas sah dan berjalan benar, tetapi variabel nilai dan err kini menempati seluruh sisa fungsi. Pembaca kode harus memindai ke bawah untuk memastikan apakah kedua variabel dipakai lagi, dan nama nilai atau err tidak bisa dipakai ulang untuk keperluan lain tanpa menimpa nilai lama. Pada fungsi panjang, tumpukan variabel sementara semacam ini cepat membuat kode sulit dibaca.
Bentuk if dengan Initializer #
Go memperbolehkan if diawali satu statement pendek sebelum kondisi, dipisahkan tanda titik koma. Bentuk lengkapnya adalah if statement; kondisi { ... }. Statement di sisi kiri dieksekusi tepat sebelum kondisi dievaluasi, dan variabel yang dideklarasikan di sana hanya hidup di dalam rantai if/else tersebut. Program berikut memakai bentuk ini dua kali untuk mengonversi dua input berbeda — satu input angka yang sah dan satu input teks yang gagal dikonversi:
package main
import (
"fmt"
"strconv"
)
func main() {
input := "42"
if nilai, err := strconv.Atoi(input); err != nil {
fmt.Println("Konversi gagal:", err)
} else {
fmt.Printf("Input %q dikonversi menjadi angka %d\n", input, nilai)
}
salah := "empat puluh dua"
if nilai, err := strconv.Atoi(salah); err != nil {
fmt.Println("Konversi gagal:", err)
} else {
fmt.Printf("Input %q dikonversi menjadi angka %d\n", salah, nilai)
}
fmt.Println("Program selesai tanpa berhenti di tengah jalan.")
}Jalankan program dari direktori chapter dengan perintah berikut:
go run if-initializer.goOutput yang Dihasilkan:
Input "42" dikonversi menjadi angka 42
Konversi gagal: strconv.Atoi: parsing "empat puluh dua": invalid syntax
Program selesai tanpa berhenti di tengah jalan.Mari kita telaah baris demi baris program di atas:
- Baris 3-6 (
import "fmt"danstrconv): mengimpor dua package —fmtuntuk mencetak output danstrconvuntuk konversi teks menjadi angka. - Baris 10 (
input := "42"): menyimpan input pertama berupa string yang berisi angka. - Baris 12 (
if nilai, err := strconv.Atoi(input); err != nil): bagian sebelum titik koma memanggilstrconv.Atoiyang mengembalikan dua nilai — angka hasil konversi dan galat. Kondisierr != nilmemeriksa apakah galat terjadi. - Baris 13 (
fmt.Println("Konversi gagal:", err)): cabang ini berjalan ketikaerrtidaknil; detail pesannya diberikan olehstrconv. - Baris 15 (
fmt.Printf(...)): cabangelseberjalan ketika konversi berhasil. Variabelnilaidari initializer tetap dapat dibaca di sini karena cabangelsemasih satu rantai denganif. - Baris 19-25 (
salah := "empat puluh dua"danifkedua): memakai namanilaidanerrkembali tanpa konflik, karena variabel dari initializerifpertama sudah tidak hidup lagi setelah rantainya selesai. - Baris 27: mencetak pesan penutup. Program tidak pernah berhenti di tengah jalan meski ada input yang gagal dikonversi, karena kedua cabang hanya mencetak pesan.
Ruang Lingkup yang Sempit dan Pola err != nil #
Variabel dari initializer tidak dapat diakses setelah rantai if/else selesai. Menambahkan fmt.Println(nilai) setelah blok pada contoh di atas membuat kompilator menolak program dengan pesan undefined: nilai. Pembatasan ini disengaja: variabel yang hidupnya pendek membuat pembaca kode langsung tahu bahwa variabel tersebut hanya relevan untuk satu keputusan.
Bentuk if v, err := operasi(); err != nil adalah idiom paling sering Anda temui di Go, mulai dari membaca berkas sampai query database. Galat di Go adalah nilai biasa yang dikembalikan fungsi — bukan mekanisme lempar-terkecuali — sehingga pengecekan seperti ini mengalir alami di dalam if. Kita akan membedah tipe error secara tuntas pada Section Error Handling
.
Percabangan bertingkat yang panjang bukan satu-satunya cara menyusun keputusan. Ketika program membandingkan satu nilai terhadap banyak kemungkinan, switch memberikan bentuk yang jauh lebih rapi — topik chapter berikutnya.
Referensi #
- Spesifikasi Go: If statements
— definisi resmi bentuk
ifdengan statement pendek. - Effective Go: if
— contoh idiom
if err != nildari tim Go. - Dokumentasi package strconv
— rujukan fungsi
Atoidan sejenisnya.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
if-initializer.go
Unduh berkaspackage main
import (
"fmt"
"strconv"
)
func main() {
input := "42"
if nilai, err := strconv.Atoi(input); err != nil {
fmt.Println("Konversi gagal:", err)
} else {
fmt.Printf("Input %q dikonversi menjadi angka %d\n", input, nilai)
}
salah := "empat puluh dua"
if nilai, err := strconv.Atoi(salah); err != nil {
fmt.Println("Konversi gagal:", err)
} else {
fmt.Printf("Input %q dikonversi menjadi angka %d\n", salah, nilai)
}
fmt.Println("Program selesai tanpa berhenti di tengah jalan.")
}