Skip to main content

A.4. Variabel

Rust merupakan bahasa yang kalau dikategorikan berdasarkan type system-nya adalah statically typed, yang artinya semua tipe data harus diketahui saat kompilasi (compile time).

Pada chapter ini kita akan belajar mengenai variabel pada Rust, cara deklarasinya, dan juga mengenai immutability variabel.

A.4.1. Deklarasi variabel menggunakan let

Keyword let digunakan untuk deklarasi variabel. Notasinya kurang lebih seperti berikut. Di contoh ini sebuah variabel bernama nama_variabel didefinisikan dan diisi nilainya dengan sebuah string "predefined value".

fn main() {
let nama_variabel = "predefined value";
println!(nama_variabel);
}

Ok, sekarang coba jalankan, dan lanjut ke pembahasan di bawah.

◉ Aturan penamaan variabel (naming convention)

Naming convention variabel di Rust adalah snake case. Nama variabel dituliskan dalam huruf kecil dengan separator tanda garis bawah atau underscore (_). Contohnya seperti: nama_variabel, hasil_operasi_pembagian, kota_kelahiran, dll.

◉ Macro println untuk print string

variabel rust

Error? kok bisa?

Perlu diketahui bahwa pada penggunaan macro println, parameter pertama wajib diisi dengan sebuah string literal. Contohnya seperti "Hello, world!". String literal yang ditampung terlebih dahulu dalam variabel, kemudian variabel-nya di print, akan menghasilkan error, contohnya seperti di atas.

Solusinya bagaimana? ya tetap menggunakan string literal, tapi dengan menerapkan teknik formatted print.

Sekarang ubah kode menjadi seperti ini:

let nama_variabel = "predefined value";
println!("{}", nama_variabel);

Bisa dilihat argument pertama statement macro println adalah string literal "{}". String {} pada macro tersebut akan di-replace dengan isi argument setelahnya, yaitu nama_variabel.

Jika dijalankan, maka hasilnya tidak ada error dan menampilkan output sesuai harapan.

string literal println

Ok sekarang kembali ke topik, yaitu perihal variabel.

A.4.2. Immutability pada variabel

Tulis kode berikut. Ada 2 variabel yang dideklarasikan, message_number yang isinya numerik, dan message1 yang isinya string.

let message_number = 1;
let message1 = "hello";
println!("message number {}: {}", message_number, message1);

Jalankan, hasilnya tidak ada error, aman.

var immutability

O iya, jika ingin menampilkan banyak variabel via macro println, manfaatkan string {}.

Tulis {} sejumlah variabel yang ingin ditampilkan, pada output string {} akan di-replace oleh variabel yang disisipkan pada argument saat pemanggilan macro println secara berurutan.

Pada contoh di atas, string "message number {}: {}"
... akan menjadi "message number {message_number}: {message1}"
... kemudian menghasilkan "message number 1: hello"

Sekarang ubah isi message_number menjadi 2 lalu siapkan juga variabel message2, kurang lebih kodenya menjadi seperti berikut, kemudian jalankan.

let message_number = 1;
let message1 = "hello";
println!("message number {}: {}", message_number, message1);

message_number = 2;
let message2 = "world";
println!("message number {}: {}", message_number, message2);

var immutability

Error? kok bisa?

Perlu diketahui, bahwa by default semua variabel adalah immutable. Immutable itu artinya gak bisa diubah nilai/value-nya. Jadi mirip seperti konstanta.

Variabel immutable mirip seperti konstanta, tapi sebenarnya berbeda. Akan kita bahas lebih detail di beberapa chapter berbeda perihal perbedaannya.

Lalu bagaimana cara agar nilai variabel bisa diubah? Caranya dengan menambahkan keyword mut (yang merupakan kependekan dari mutable) saat pendefinisian variabel tersebut.

Catatan tambahan:

  • Operasi assignment pada variabel immutable hanya boleh dilakukan sekali. Dan pada kode di atas telah dicontohkan caranya bagaimana. Variabel dideklarasikan sekaligus diisi nilainya.

  • Perlu diketahui bahwa sebenarnya diperbolehkan untuk memecah statement deklarasi variable dan assignment nilai sebagai 2 statement terpisah. Lebih jelasnya dibahas setelah ini pada section section A.4.5.

A.4.3. Keyword mut

Ok, mari kita coba, ubah statement deklarasi variabel message_number, tambahkan keyword mut. Lalu jalankan ulang program.

let mut message_number = 1;
let message1 = "hello";
println!("message number {}: {}", message_number, message1);

message_number = 2;
let message2 = "world";
println!("message number {}: {}", message_number, message2);

mut keyword

Ok, sekarang tidak muncul error.

Dengan menggunakan keyword let mut pada pendefinisian message_number, membuat variabel tersebut menjadi mutable atau bisa diubah nilainya.

◉ Argument parameter macro println

Selanjutnya, coba tambahkan lagi 1 message baru pada program yang sudah dibuat, lalu run.

let mut message_number = 1;
let message1 = "hello";
println!("message number {}: {}", message_number, message1);

message_number = 2;
let message2 = "world";
println!("message number {}: {}", message_number, message2);

message_number = 3;
let message3: i8 = 24;
println!("message number {1}: {0}", message3, message_number);

formatted print macro `println`

Jika dilihat ada yg berbeda pada cara deklarasi variabel message3 dan juga pada statement println untuk message3 yang di situ digunakan {1} dan {0}, tidak seperti sebelumnya yg menggunakan {}. Kita akan bahas yg ke-2 terlebih dahulu.

  • Jika menggunakan {}, maka string akan di-replace sesuai urutan argument pada pemanggilan println.
  • Jika menggunakan {0}, maka string akan di-replace dengan data pada argument ke 1 pemanggilan fungsi println, yang pada contoh di atas adalah message3.
  • Jika menggunakan {1}, maka string akan di-replace dengan data pada argument ke 2 pemanggilan fungsi println, yang pada contoh di atas adalah message_number.
  • Jika menggunakan {n}, maka string akan di-replace dengan data pada argument ke n+1 pemanggilan fungsi println.

Dengan ini maka 3 statement berbeda berikut akan menghasilkan output yang sama:

println!("message number {}: {}", message_number, message3);
println!("message number {0}: {1}", message_number, message3);
println!("message number {1}: {0}", message3, message_number);

Sekarang perihal perbedaan cara deklarasi message3 akan kita bahas di bawah ini.

A.4.4. Type Inference vs Manifest Typing

Rust mendukung dua metode deklarasi variabel, yaitu type inference dan manifest typing.

◉ Metode Type Inference

Penulisan variabel dengan metode ini ditandai dengan tidak menuliskan tipe data secara jelas/eksplisit. Contoh:

let var1 = "hello" // compiler akan secara cerdas mendeteksi var1 tipe data nya string
let var2 = 12 // compiler akan secara cerdas mendeteksi var2 tipe data nya numerik

Metode deklarasi yang selama ini sudah kita terapkan adalah type inference.

◉ Metode Manifest Typing

Metode ini mewajibkan programmer untuk menuliskan secara jelas/eksplisit tipe data variabel. Contoh penerapannya bisa dilihat di praktik sebelumnya, pada definisi variabel message3.

let message3: i8 = 24;

Notasi penulisan tipe data adalah namavariabel: tipedata. Contoh seperti di atas, yaitu let message3: i8 = 24 artinya variabel message3 didefinisikan memiliki tipe data i8.

i8 merupakan salah satu tipe data dari sekian banyak tipe data yang ada di Rust. Lebih jelasnya kita akan bahas pada chapter selanjutnya.

A.4.5. Deklarasi variabel tanpa predefined value

Sesuai dengan penjelasan di dokumentasi spesifikasi Rust, variable yang tidak ada value-nya akan memunculkan error saat program di-run.

Meski demikian, diperbolehkan untuk memisahkan variable statement untuk deklarasi variable dan pengisian value. Sebagai contoh, statement message_number pada kode berikut ...

let message_number = 1;
println!("message number {}", message_number);

... boleh dituliskan dalam 2 statement terpisah seperti ini:

let message_number: i32;
message_number = 1;
println!("message number {}", message_number);

Intinya, operasi assignment hanya diperbolehkan 1x saja pada variabel immutable, baik itu saat deklarasi variable atau setelahnya.

A.4.6. Deklarasi banyak variabel dalam satu statement

Di Rust memungkinkan untuk mendefinisikan banyak variabel dalam 1 baris statement. Notasi penulisannya seperti berikut:

let (var1, var2) = (24, "hello");
println!("var1: {0}", var1); // hasilnya => var1: 24
println!("var2: {0}", var2); // hasilnya => var2: hello

Pendefinisian banyak variabel dalam 1 statement dilakukan dengan menuliskan semua variabelnya dengan separator tanda , dan diapit tanda kurung ().

Sebagai contoh di atas 2 variabel didefinisikan, yaitu var1 dan var2, dan keduanya memiliki value yang berbeda tipe-datanya.

Bisa juga saat definisi variabel sekaligus ditentukan tipe data variabel, notasi penulisan bisa dilihat pada contoh kode berikut:

let (var3, var4): (i8, i8) = (32, 12);
println!("var3: {0}", var3); // hasilnya => var3: 32
println!("var4: {0}", var4); // hasilnya => var4: 12

Dengan notasi ini bisa juga untuk definisi variabel mutable. Cukup tambahkan keyword mut pada variabel yang ingin bisa diubah nilainya.

let (var5, mut var6, var7): (i8, i8, i8) = (64, 12, 4);
println!("var5: {0}", var5); // hasilnya => var5: 64
println!("var6: {0}", var6); // hasilnya => var6: 12
var6 = 24;
println!("var6: {0}", var6); // hasilnya => var6: 24
println!("var7: {0}", var7); // hasilnya => var7: 4

A.4.7. Deklarasi variabel dengan tipe data ditentukan dari value

Ini merupakan salah satu alternatif cara penulisan untuk men-specify tipe data variabel, caranya dengan menuliskan tipe data tepat setelah value, contohnya seperti berikut:

let data1 = 24i8;
println!("data1: {0}", data1); // hasilnya => data1: 24

Variabel data didefinisikan dengan predefined value adalah numerik 24 dengan tipe data i8, penulisan value nya menjadi 24i8.

Boleh juga menggunakan separator _ dalam penulisan value-nya sebagai pembatas antara nilai dan tipe data, contoh:

let data1 = 24_i8;
println!("data1: {0}", data1); // hasilnya => data1: 24

A.4.8. Variable Shadowing

Di Rust ada konsep bernama variable shadowing. Shadowing sendiri adalah pendefinisan ulang variabel yang sebelumnya sudah didefinisikan. Biasanya teknik ini dipakai untuk isolasi variabel dalam sebuah blok kode.

Contoh shadowing bisa dilihat pada kode berikut:

let x = 5;
println!("x: {}", x); // hasilnya => x: 5

let x = x + 1;
println!("x: {}", x); // hasilnya => x: 6

Lebih jelasnya akan kita bahas pada chapter terpisah, yaitu Shadowing.

A.4.9. Variabel _

Di Rust, jika ada variabel yang dideklarasikan tapi tidak digunakan, maka muncul warning saat ekesekusi program.

Pada praktiknya, tidak semua variabel memang perlu untuk digunakan. Pada kasus tertentu suatu variabel harus tetap dideklarasikan untuk menampung suatu nilai meski tidak digunakan. Misalnya pada case dimana ada pemanggilan fungsi yang nilai baliknya tidak digunakan.

Untuk case seperti yang dijelaskan di atas, gunakan variabel _. Variabel ini berguna untuk menampung nilai yang tidak digunakan, untuk menghindari warning. Contoh:

fn main() {
let _ = run_something();
}

Catatan chapter 📑

◉ Work in progress

  • Variabel _

◉ Source code praktik

github.com/novalagung/dasarpemrogramanrust-example/../variabel

◉ Chapter relevan lainnya

◉ Referensi