Topik ini membahas cara menyimpan nilai di dalam variabel Rust dengan let, alasan variabel Rust bersifat tidak dapat diubah secara bawaan, cara mengizinkan perubahan dengan mut, serta mekanisme shadowing yang membuat variabel baru bernama sama. Setelah membacanya, pembaca dapat memilih secara sadar antara variabel yang dapat diubah dan yang tidak, serta membedakan keduanya dari konstanta.
Variabel dengan let#
Variabel dibuat dengan pernyataan let yang diikuti nama variabel, tanda sama dengan, dan nilai awalnya. Nilai tersebut tersimpan untuk dipakai pada baris-baris berikutnya, seperti pada program berikut.
fn main() {
let x = 5;
println!("nilai x: {x}");
}nilai x: 5Tipe variabel tidak perlu dituliskan karena Rust menyimpulkannya dari nilai yang diberikan. Nilai 5 pada konteks ini menghasilkan tipe i32, yaitu tipe bilangan bulat bertanda yang menjadi pilihan bawaan compiler ketika tidak ada petunjuk lain. Penyimpulan tipe (type inference) ini tidak mengubah sifat Rust sebagai bahasa bertipe statis, sebab tipe setiap variabel tetap ditetapkan sepenuhnya saat kompilasi dan tidak berubah lagi selama variabel hidup. Nama variabel ditulis dengan huruf kecil dan kata dipisah garis bawah, misalnya nilai_maks atau sisa_kursi, dan konvensi ini dijaga compiler lewat peringatan non_snake_case apabila nama seperti NilaiMaks dipakai.
Variabel tidak dapat diubah secara bawaan#
Satu keputusan desain Rust yang membedakannya dari banyak bahasa lain adalah variabel yang dibuat dengan let bersifat tidak dapat diubah (immutable) sejak awal. Penugasan nilai baru ke variabel semacam itu ditolak compiler. Program berikut sengaja berisi kesalahan tersebut.
printf 'fn main() {\n let x = 5;\n println!("nilai x: {x}");\n x = 6;\n}\n' > salah.rs
rustc --edition=2021 salah.rs 2>&1 | sed -n '1,14p'error[E0384]: cannot assign twice to immutable variable `x`
--> salah.rs:4:5
|
2 | let x = 5;
| - first assignment to `x`
3 | println!("nilai x: {x}");
4 | x = 6;
| ^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
2 | let mut x = 5;
| +++Error E0384 menunjuk baris penugasan ulang dan menawarkan perbaikan berupa penambahan mut pada deklarasi. Baris penugasan pertama ikut ditandai sehingga asal variabel mudah dilacak. Pesan error yang sekaligus memuat saran perbaikan merupakan pola umum compiler Rust, sehingga membaca keluaran kompilasi menjadi kebiasaan yang produktif.
Kata kunci mut#
Ketika sebuah variabel memang perlu berubah, tambahkan kata kunci mut di antara let dan nama variabel. Variabel menjadi dapat diubah (mutable) dan menerima penugasan nilai baru berapa kali pun sepanjang tipenya sama.
fn main() {
let mut hitung = 0;
hitung = hitung + 10;
hitung += 5;
println!("total hitung: {hitung}");
}total hitung: 15Operator gabungan seperti += meringkas penugasan dan operasi aritmetika menjadi satu baris. Kata kunci mut juga berfungsi sebagai sinyal dokumentasi: pembaca kode langsung mengetahui variabel mana yang berubah di sepanjang program. Karena itu, tambahkan mut hanya pada variabel yang benar-benar berubah supaya sinyal tersebut tetap tajam. Ketika nilai tidak pernah diubah, variabel immutable memberi jaminan kepada pembaca bahwa nilainya tetap dari deklarasi sampai akhir lingkup.
Compiler turut menjaga sinyal ini dari arah sebaliknya. Variabel mut yang tidak pernah diberi nilai baru memicu peringatan variable does not need to be mutable, sehingga kata kunci yang tidak terpakai tetap terlihat dan mudah dibersihkan.
Shadowing#
Shadowing terjadi ketika deklarasi let baru menggunakan nama yang sama dengan variabel sebelumnya. Variabel baru menutupi variabel lama sejak baris deklarasi tersebut, sementara variabel lama tetap menyimpan nilai aslinya di balik nama yang sama.
fn main() {
let x = 5;
let x = x + 1;
{
let x = x * 2;
println!("x di dalam lingkup dalam: {x}");
}
println!("x di luar lingkup dalam: {x}");
}x di dalam lingkup dalam: 12
x di luar lingkup dalam: 6Nilai x menjadi 6 setelah shadowing pertama, lalu lingkup dalam menghitung 12 dari nilai tersebut. Setelah kurung kurawal lingkup dalam ditutup, shadowing di dalamnya berakhir dan nama x kembali menunjuk variabel bernilai 6. Keunggulan utama shadowing adalah tipe variabel baru boleh berbeda dari yang lama, sehingga satu nama dapat dipakai ulang untuk tahap pengolahan yang berbeda.
fn main() {
let spasi = " ";
println!("tipe teks, panjang byte: {}", spasi.len());
let spasi = spasi.len();
println!("sekarang bilangan: {spasi}");
}tipe teks, panjang byte: 3
sekarang bilangan: 3Konstanta#
Konstanta dideklarasikan dengan const dan menyerupai variabel immutable, tetapi aturannya lebih ketat. Anotasi tipe wajib ditulis, nilainya harus dapat dihitung saat kompilasi, dan penamaannya memakai huruf besar dengan garis bawah. Konstanta juga dapat dideklarasikan di luar fungsi sehingga berlaku untuk seluruh berkas.
const MAKS_PESERTA: u32 = 100;
fn main() {
let peserta = 24;
let sisa = MAKS_PESERTA - peserta;
println!("sisa kursi: {sisa}");
}sisa kursi: 76Kata kunci mut tidak berlaku pada konstanta karena nilainya memang tidak pernah berubah. Nilai konstanta juga tidak boleh merupakan hasil pemanggilan fungsi atau nilai yang baru diketahui saat program berjalan, misalnya hasil pembacaan masukan pengguna. Perbedaan penting di antara keduanya dirangkum pada tabel berikut.
| Aspek | Variabel let | Konstanta const |
|---|---|---|
| Sifat nilai | dapat berubah dengan mut | selalu tetap |
| Anotasi tipe | opsional, dapat disimpulkan | wajib ditulis |
| Nilai yang diterima | nilai apa pun saat program berjalan | nilai yang diketahui saat kompilasi |
| Penamaan | huruf kecil bergaris bawah | huruf besar bergaris bawah |
| Lingkup | dari deklarasi sampai akhir lingkup | lingkup item, termasuk luar fungsi |
Konstanta dapat dideklarasikan di luar fungsi dan dipakai di seluruh berkas, sedangkan variabel let di luar fungsi tidak sah. Ketika sebuah nilai bersifat tetap dan bermakna global, konstanta memberi jaminan yang lebih kuat daripada variabel immutable.
Kesalahan umum#
Menambahkan mut pada semua variabel. Kebiasaan ini menghapus manfaat utama variabel immutable karena penugasan yang tidak disengaja tidak lagi terdeteksi. Tambahkan mut hanya setelah compiler menolak penugasan yang memang disengaja.
Menganggap shadowing sebagai perubahan nilai. Shadowing tidak mengubah isi variabel lama, melainkan membuat variabel baru yang menutupi nama lama. Nilai variabel lama tetap ada dan dapat dipakai lagi begitu lingkup shadowing berakhir, sehingga pola ini bukan pengganti mut untuk memperbarui data secara berkelanjutan. Gunakan shadowing untuk transformasi bertahap yang menghasilkan nilai baru, dan gunakan mut untuk pembaruan nilai yang berlangsung terus-menerus seperti penghitung.
Ringkasan#
letmembuat variabel yang tipenya disimpulkan compiler dan bersifat immutable secara bawaan.- Penugasan ulang variabel immutable menghasilkan error E0384, dengan saran perbaikan berupa penambahan
mut. mutmengizinkan perubahan isi variabel dengan tipe yang tetap, sekaligus menjadi penanda niat di dalam kode.- Shadowing membuat variabel baru bernama sama, boleh dengan tipe berbeda, dan berlaku sampai akhir lingkupnya.
constmenuntut anotasi tipe, nilai yang diketahui saat kompilasi, dan tidak dapat dipasangkanmut.
Referensi#
- Variables and Mutability — The Rust Book
— Dasar
let,mut, shadowing, serta perbedaan konstanta dan variabel. - Variable bindings — Rust by Example — Contoh pengikatan variabel beserta lingkupnya.
- Mutability — Rust by Example — Perbandingan variabel mutable dan immutable dalam contoh singkat.