Dasar-Dasar
if di Zero kurang lebih terlihat seperti if di bahasa keluarga C lainnya, dengan satu batasan penting: kondisinya harus berupa bool.
Kondisi value == 42 adalah bool karena == antara dua i32 mengembalikan bool. Masing-masing dari kedua cabang berisi blok pernyataan. Salah satu cabang bisa dibilang boleh dihilangkan, karena else bersifat opsional, tetapi kalau keduanya ada, keduanya harus berupa blok { ... }.
Wajib bool
Beberapa bahasa membolehkan kamu menulis if value { ... } dan menganggap 0, "", atau null sebagai falsy. Zero tidak. Kondisinya harus berupa bool yang sungguhan.
let count = 0
if count { // compile error: expected bool, got i32
// ...
}
if count == 0 { // OK
check world.out.write("nothing to do\n")
}
Alasannya sama dengan yang berlaku di seluruh bahasa ini: eksplisit lebih baik daripada implisit. Agen yang membaca bentuk kedua tahu persis apa yang sedang diperiksa. Bentuk pertama membiarkan aturan truthiness tetap implisit, dan aturan itu berbeda-beda di tiap bahasa, jadi Zero memilih untuk tidak memakainya.
Else dan Else-If
Klausa else dijalankan saat kondisinya false:
Rangkai kondisi dengan else if:
if value < 0 {
check world.out.write("negative\n")
} else if value == 0 {
check world.out.write("zero\n")
} else {
check world.out.write("positive\n")
}
else if sebenarnya hanyalah else { if ... } tanpa kurung kurawal. Artinya sama, indentasinya lebih sedikit. else terakhir bersifat opsional.
Dari Mana Kondisi Berasal
Kondisi bisa berupa apa saja yang menghasilkan bool:
- Binding
bool:if ok { ... }. - Perbandingan:
if value == 42 { ... },if x < y { ... }. - Kombinasi logika:
if a && b { ... },if pair.left == 1_u8 && pair.right == 2_u8 { ... }. - Pemanggilan fungsi yang mengembalikan
bool:if isReady(world) { ... }.
Potongan kode nyata dari contoh-contoh bahasa ini:
let pair: BytePair = Pair { left: 1_u8, right: 2_u8 }
if pair.left == 1_u8 && pair.right == 2_u8 {
check world.out.write("type alias ok\n")
} else {
check world.out.write("type alias broke\n")
}
&& melakukan short circuit seperti yang kamu harapkan: kalau sisi kiri bernilai false, sisi kanan tidak dievaluasi. Hal yang sama berlaku untuk ||.
Kapan Memakai match
Rangkaian if/else if cocok untuk keputusan dua atau tiga arah, terutama saat kondisinya tidak punya struktur yang sama. Tetapi saat kamu membuat percabangan berdasarkan varian sum type, yaitu choice atau enum, match adalah alat yang tepat.
Bandingkan:
// match - exhaustive, compiler-checked
match result {
.ok => value { check world.out.write("ok\n") }
.err => message { check world.out.write("err\n") }
}
dengan:
// if/else over a sum type - verbose and easier to get wrong
if result.isOk() {
let value = result.unwrap()
check world.out.write("ok\n")
} else {
check world.out.write("err\n")
}
Bentuk match membuat analisis varian menjadi eksplisit, dan compiler akan protes kalau nanti ada varian baru yang lupa kamu tangani. Bentuk if diam-diam meneruskan apa pun yang bukan ok ke cabang else, termasuk varian baru yang belum pernah terpikirkan olehmu.
Panduan singkatnya: if untuk boolean, match untuk varian.
Catatan Gaya
Beberapa konvensi kecil yang membuat kode lebih mudah dibaca oleh manusia dan agen:
- Selalu pakai kurung kurawal untuk isi cabang. Isi satu baris pun ditulis di dalam
{ ... }. Tidak ada bentuk satu pernyataan tanpa kurung kurawal. Ini disengaja, supaya indentasi tetap bisa diandalkan dan satu sumber bug yang umum di keluarga C hilang. - Taruh cabang yang paling sering terjadi di urutan pertama. Pembaca (dan agen) membaca sekilas dari atas ke bawah.
- Pilih kondisi positif kalau sama jelasnya.
if isReadylebih mudah diikuti daripadaif !notReady, kalau hal lainnya sama.
Berikutnya: Perulangan While
Percabangan menentukan apa yang dilakukan, sedangkan perulangan menentukan berapa kali melakukannya. Dokumen berikutnya membahas while loop di Zero, konstruksi perulangan versi awal yang disediakan bahasa ini.
Pertanyaan yang sering diajukan
Bagaimana cara kerja pernyataan if di Zero?
Pakai if condition { ... } dengan klausa else { ... } yang opsional. Kondisinya harus berupa bool, karena Zero tidak mengubah integer, string, atau nilai lain menjadi boolean secara otomatis. Contoh: if value == 42 { check world.out.write("yes\n") } else { check world.out.write("no\n") }.
Apakah Zero punya operator ternary?
Zero sengaja menjaga bahasanya tetap kecil dan memakai blok if / else, bukan operator ternary condition ? a : b yang terpisah. Contoh-contoh resminya lebih memilih cabang yang eksplisit, bahkan untuk kasus yang singkat. Kalau bahasamu mendukung if sebagai ekspresi, kemungkinan besar Zero akan condong ke arah itu daripada menambahkan sintaks kedua.
Apakah if/else if bisa dirangkai di Zero?
Bisa. Rangkai kondisi dengan menulis else if di antara cabang: if a { ... } else if b { ... } else { ... }. Untuk percabangan yang lebih rumit atas sebuah choice atau enum, lebih baik pakai match, karena lebih menyeluruh dan compiler memeriksa bahwa kamu sudah menangani setiap varian.
Kenapa Zero tidak mengubah nilai menjadi bool secara otomatis?
Filosofi desain Zero adalah 'semuanya eksplisit'. Truthiness implisit, yaitu menganggap 0, "", atau null sebagai false, sering menjadi sumber bug dan sulit dinalar secara tepat oleh agen. Mewajibkan bool yang sungguhan membuat keputusan percabangan terlihat di kode sumber dan lebih mudah diverifikasi secara mekanis.
Kapan sebaiknya memakai match daripada if/else?
Pakai match saat kamu membuat percabangan berdasarkan varian sebuah choice atau enum. Compiler bisa memastikan kamu sudah menangani setiap kasus, sesuatu yang tidak bisa dilakukan rangkaian if/else if. Simpan if/else untuk predikat boolean sederhana: pemeriksaan kesamaan, perbandingan, dan percabangan dua arah yang singkat.