Bahasa Pemrograman Rust 2: Variabel, Mutability, dan Tipe Data
Variabel
Pada bahasa Rust, kita dapat mendeklarasikan variabel dengan tiga keyword berikut: const, static, dan let.
Variabel const tidak akan dapat diubah atau immutable. Variabel static dapat diubah, namun membutuhkan keyword unsafe
karena operasi ini tidak aman bagi memory. Untuk let, let merupakan keyword paling umum untuk mendefinisikan variabel
dalam Rust. Tidak seperti static dan const, let TIDAK DAPAT digunakan diluar fungsi. Bila anda menggunakan static maupun
const, anda harus mendefinisikan tipe datanya secara eksplisit, sedangkan let tidak perlu karena compiler akan menentukannya sendiri. Namun untuk contoh di artikel ini di bagian bawah, saya akan terus mendefinisikan tipe datanya secara eksplisit untuk memperjelas.
Keyword let memliki tipe data default. Bila anda me-assign sebuah nilai integer contohnya kepada variabel yang dideklarasikan dengan
keyword let, maka integer tersebut otomatis akan menjadi 32 bit integer (i32). Bila anda ingin memakai 8 bit integer, maka anda harus
menuliskannya secara eksplisit. Hal ini juga berlaku pada nilai float.
1
2
3
4
5
6
7
8
9
const FOO: i8 = 10;
static BAR: i8 = 1;
fn main() {
// i32
let baz = 3;
// i8
let qux: i8 = 4;
}
Mutability
Berikutnya adalah mutability, atau bisa tidaknya variabel tersebut diubah nilainya. Secara default, variabel dalam rust semuanya
immutable atau tidak dapat diubah. Untuk membuat sebuah variabel mutable atau dapat diubah, diperlukan sebuah keyword yang bernama mut. mut memungkinkan kita
untuk re-assign atau memberikan nilai kembali pada suatu variabel. Bila anda mengubah nilai dari suatu variabel tanpa keyword mut, maka akan terjadi error.
1
2
3
4
5
6
7
8
fn main() {
let mut x = 10;
// Output: 10
println!("{}", x);
x = 5;
// Output: 5
println!("{}", x);
}
Tipe Data dalam Bahasa Rust
Primitive Type
| Tipe Data | Nama Tipe |
|---|---|
i8 |
8-bit Integer |
i16 |
16-bit Integer |
i32 |
32-bit Integer |
i64 |
64-bit Integer |
i128 |
128-bit Integer |
u8 |
8-bit Unsigned Integer |
u16 |
16-bit Unsigned Integer |
u32 |
32-bit Unsigned Integer |
u64 |
64-bit Unsigned Integer |
u128 |
128-bit Unsigned Integer |
f32 |
32-bit Floating Point |
f64 |
64-bit Floating Point |
f128 |
128-bit Float |
str |
String Slices |
bool |
Boolean |
char |
Character |
array |
Array dengan ukuran tetap |
usize |
Unsigned Integer dengan ukuran Pointer |
tuple |
Tuple |
slice |
Slice |
isize |
Signed Integer dengan ukuran Pointer |
Penggunaan
Integer
Integer merupakan tipe data bilangan bulat dengan rentang tertentu yang memiliki batas. Berikut adalah rentang minimal dan maksimal dari setiap X-bit signed integer.
| Tipe Integer | Nilai Minimum | Nilai Maksimum |
|---|---|---|
| 8-bit Integer | -128 | 127 |
| 16-bit Integer | -32768 | 32767 |
| 32-bit Integer | -2147483648 | 2147483647 |
| 64-bit Integer | -9223372036854775808 | 9223372036854775807 |
| 128-bit Integer | −2^127 | 2^127 - 1 |
Saya menuliskan 128-bit Integer dalam bentuk pangkatnya dikarenakan nilainya sangatlah besar. Untuk penggunaan, gunakan Integer untuk menyetor bilangan bulat tanpa koma, dan pakai tipe Integer seefektif mungkin dengan memperhatikan batas jarak yang tertera diatas.
1
2
3
4
5
6
7
fn main() {
let a: i8 = 127;
let b: i16 = 32767;
let c: i32 = 2147483647;
// Dan seterusnya
}
Contoh penggunaan pada aritmatika:
1
2
3
4
5
6
fn main() {
let x = 42;
let y = 200;
// OUTPUT: 242
println!("{}", x + y);
}
Untuk unsigned integer, itype, dan utype tidak akan dibahas disini, dikarenakan topik-topik tersebut merupakan topik yang lebih tinggi lagi.
Float
Float atau Floating Point merupakan tipe data yang menyimpan bilangan desimal.
1
2
3
4
fn main() {
let x: f32 = 252.25;
let y: f64 = 200.42;
}
Float juga dapat diimplementasikan untuk bilangan bulat, namun membutuhkan titik dan 0 dibelakangnya.
1
2
3
fn main() {
let x: f32 = 3.0;
}
Char
Char merupakan tipe data karakter yang hanya memuat satu buah karakter dengan besar 4-bit. Pendeklarasian char menggunakan tanda petik satu quote karena dua petik digunakan untuk string slice.
1
2
3
fn main() {
let x: char = 'a';
}
String Slice
String Slice (str) merupakan satu dari dua tipe string utama dimana yang satunya lagi merupakan tipe String yang bukan merupakan tipe primitif. Tipe str selalu dalam kondisi borrowed yang nanti akan dibahas di bab Ownership. String Slice tersimpan dalam stack memory.
1
2
3
fn main() {
let x: &str = "Tipe String Slice";
}
Boolean
Boolean merupakan tipe data yang hanya menyimpan salah satu dari dua buah value yakni true atau false.
1
2
3
4
fn main() {
let x: bool = true;
let y: bool = false;
}
Array
Array memiliki ukuran tetap di memori. Cara pendeklarasiannya adalah sebagai berikut: let nama: [tipe; ukuran] = [elm1, elm2, elm3].
1
2
3
fn main() {
let array: [i32; 3] = [0, 1, 2];
}
Tuple
Tuple merupakan tipe yang heterogen. Ia dapat menyimpan banyak tipe data berbeda didalamnya. Elemen dalam tuple dapat diakses dengan menggunakan tanda titik setelah nama variabel tuple tersebut kemudian menuliskan index dari elemen tersebut.
1
2
3
4
5
6
fn main() {
let tuple = ("Saya tuple", 22, [2,3,4], 24.5);
let elemen_pertama = tuple.0;
// OUTPUT: Saya tuple
println!("{}", elemen_pertama);
}
Slice
Slice berukuran dinamis, sebuah koleksi dari elemen. Slice biasanya digunakan untuk mengambil sejumlah potongan dari dalam array.
1
2
3
4
5
6
7
8
9
fn main() {
let array: [&str; 5] = ["hai", "hoi", "halo", "hey", "hoi"];
let slice = &array[0..3];
// OUTPUT: hai hoi halo
for i in slice {
print!("{} ", i);
}
}
Slice diatas mengambil elemen ke-0 sampai elemen ke-2 array tersebut. Bila anda tidak tahu, tanda & diatas merupakan tanda reference yang akan dibahas nanti.
Beberapa Tipe Non-Primitif
String
String merupakan tipe heap dinamis seperti Vec. Pendeklarasian String dapat dilakukan dengan beberapa cara.
1
2
3
4
5
6
7
8
fn main() {
let a: String = String::from("Aku adalah String");
let b: String = "Aku adalah String".to_string();
let c: String = "Aku adalah String".into();
let mut d: String = String::new();
d.push_str("Aku adalah String");
}
Vec (Vector)
Vec merupakan tipe data vector atau array dinamis yang tersimpan dalam memory heap. Vector dapat kita gunakan untuk menyimpan tipe data apapun termasuk User-defined data types atau tipe data yang kita definisikan sendiri. Pendeklarasian Vec untuk memasukkan value secara langsung menggunakan sebuah macro yang bernama vec! sedangkan secara tidak langsung, kita menggunakan method push() yang akan memasukkan value kedalam vector tersebut. Menggunakan push() membutuhkan variabel untuk mutable atau dapat dirubah.
1
2
3
4
5
6
7
8
fn main() {
// Dengan macro
let x: Vec<i32> = vec![224, 215, 364, 241];
// Dengan push()
let mut y: Vec<i32> = Vec::new();
y.push(123);
}