Pada Chapter sebelumnya kita mengalami kejadian aneh: satu titik koma membuat fungsi gagal dikompilasi. Kompiler menyebut tubuh fungsi “mengembalikan ()” padahal baris terakhirnya berisi total / 10 yang jelas-jelas angka. Kejadian itu bukan keanehan, melainkan pintu masuk ke salah satu konsep paling mendasar di Rust: pembedaan antara expression dan statement. Bab-bab sebelumnya kita memakai istilah ini asal tanpa definisi. Pada Chapter ini kita akan mendefinisikan keduanya, melihat bagaimana kompiler memperlakukan keduanya secara berbeda, dan memanfaatkan pemahaman tersebut untuk menulis kode yang lebih rapat.
Statement Adalah Instruksi, Expression Adalah Nilai #
Definisi keduanya singkat tetapi berdampak besar:
- Statement adalah instruksi yang melakukan sesuatu dan tidak menghasilkan nilai yang bisa disimpan. Statement diakhiri titik koma. Contohnya:
letuntuk membuat variabel, danprintln!untuk mencetak. - Expression adalah potongan kode yang dievaluasi menjadi sebuah nilai. Expression tidak butuh titik koma; kalau ditambahkan titik koma, expression berubah menjadi statement yang membuang nilainya.
Contoh expression mencakup literal seperti 25000 dan "Kopi Susu", operasi aritmetika seperti harga * jumlah, pemanggilan fungsi seperti hitung_diskon(total), dan — nanti kita bahas tuntas di Chapter berikutnya — blok { } itu sendiri.
Mari kita bedah program sederhana dengan kacamata baru ini:
fn main() {
let harga = 25000;
let jumlah = 4;
let total = harga * jumlah;
let rincian = "Kopi Susu";
println!("{} x {} = Rp{}", rincian, jumlah, total);
}Output yang Dihasilkan:
Kopi Susu x 4 = Rp100000Mari kita klasifikasikan baris-baris kode di atas:
- Baris 1–2 (
let harga = 25000;danlet jumlah = 4;): Keduanya adalah statement — instruksi membuat variabel. Meski begitu, sisi kanannya (25000dan4) adalah expression bernilai yang dievaluasi lebih dulu sebelum diikat ke variabel. - Baris 4 (
let total = harga * jumlah;): Baris ini statementletyang sisi kanannya adalah expression kompleksharga * jumlah. Kompiler membaca nilaiharga(25000) danjumlah(4), mengalikan, laluletmengikat hasil100000ketotal. - Baris 5 (
let rincian = "Kopi Susu";): String literal adalah expression. Statementletmengikat nilai teks tersebut kerincian. - Baris 7 (
println!(...);): Macroprintln!mencetak ke layar dan menghasilkan nilai kosong(). Karena hasilnya tidak berguna, pemanggilan ini diperlakukan sebagai statement dengan titik koma.
Pola yang muncul: hampir semua baris di Rust adalah “statement di luar, expression di dalam”. Bagian kanan let adalah dunia expression yang menghasilkan nilai; bagian let-nya sendiri adalah statement yang menangkap nilai tersebut.
Expression Bisa Ditempatkan di Mana Nilai Dibutuhkan #
Aturan praktisnya satu kalimat: di mana pun sebuah nilai bisa berada, di situ pula boleh ada expression yang mengevaluasi menjadi nilai tersebut. Karena sisi kanan let menerima nilai, sisi kanan let juga menerima expression bentuk apa pun. Termasuk expression if:
fn main() {
let stok = 3;
let status = if stok > 0 { "tersedia" } else { "habis" };
println!("Status barang: {}", status);
}Output yang Dihasilkan:
Status barang: tersediaMari kita telaah cara kerja kode di atas:
- Baris 2 (
let stok = 3;): Statementletstandar mengikat nilai3kestok. - Baris 3 (
let status = if stok > 0 { ... } else { ... };): Di banyak bahasa,ifhanya mengatur alur. Di Rust,ifadalah expression yang menghasilkan nilai: cabang{ "tersedia" }dan{ "habis" }masing-masing adalah blok yang mengembalikan string. Karenastokbernilai3(lebih besar dari0), expressionifmengevaluasi menjadi"tersedia", laluletmengikatnya kestatus. - Baris 5 (
println!("Status barang: {}", status);): Nilai hasil expressionifdicetak seperti nilai variabel biasa.
Idiom let status = if ... { ... } else { ... }; menggantikan pola lama “set variabel default, lalu timpa di dalam if” yang empat-baris. Hasilnya lebih pendek dan variabel status dijamin terisi dalam satu tempat. Syaratnya satu: kedua cabang harus menghasilkan tipe yang sama, karena status hanya boleh memegang satu tipe.
Statement Tidak Bisa Ditempatkan di Mana Nilai Dibutuhkan #
Sisi kebalikannya juga berlaku: statement tidak menghasilkan nilai, jadi statement tidak boleh menempati posisi nilai. Pemula sering mencoba hal berikut:
fn main() {
let y = (let x = 5);
}Kompilasi gagal dengan galat sintaks:
error: expected expression, found `let` statement
--> src/main.rs:2:14
|
2 | let y = (let x = 5);
| ^^^Pesan tersebut menegaskan aturannya: posisi setelah tanda sama dengan adalah dunia expression, dan let x = 5 adalah statement yang tidak punya nilai untuk ditawarkan. Statement let tidak bisa ditumpuk ke dalam statement let lain, dan tidak bisa dijadikan argument pemanggilan fungsi. Kompiler menjaga perbatasan ini secara ketat.
Titik Koma Sebagai Tombol Transformasi #
Kita kini punya kosakata untuk menjelaskan jebakan titik koma dari Chapter sebelumnya. Titik koma bukan sekadar hiasan akhir baris; titik koma adalah tombol yang mengubah expression menjadi statement dan membuang nilainya:
| Kode | Kategori | Hasil |
|---|---|---|
total / 10 | Expression | Nilai hasil pembagian |
total / 10; | Statement | Nilai dibuang, menghasilkan () |
harga * jumlah | Expression | Nilai hasil perkalian |
{ total - diskon } | Expression blok | Nilai baris terakhir blok |
let total = 95000; | Statement | Tidak bernilai |
Baris terakhir tubuh fungsi adalah titik rawan. Fungsi dengan tipe kembali -> i64 menuntut baris terakhirnya berupa expression i64; menambahkan titik koma mengubahnya menjadi statement bernilai (), sehingga muncul galat mismatched types: expected i64, found (). Sekarang kita tahu persis mengapa satu karakter itu berkuasa.
Ringkasan #
Statement adalah instruksi tanpa nilai yang diakhiri titik koma, sedangkan expression adalah potongan kode yang mengevaluasi menjadi nilai dan bisa ditempatkan di posisi mana pun nilai diperlukan. Titik koma mengubah expression menjadi statement dan membuang nilainya; let adalah statement meski sisi kanannya expression; dan if di Rust adalah expression yang nilainya bisa diikat ke variabel. Satu entitas terakhir belum kita sentuh: blok { } ternyata juga expression penuh — dan itulah bintang utama Chapter berikutnya.