Konversi tipe di Rust
Rust tidak akan mengubah satu tipe ke tipe lain secara otomatis. Kalau kamu mencampur i32 dan f64 dalam satu ekspresi, kodenya tidak akan bisa dikompilasi. Kamu harus mengonversinya secara eksplisit. Ini memang disengaja: konversi diam-diam adalah sumber bug yang umum di bahasa lain.
Konversi antartipe angka dengan as
Section titled “Konversi antartipe angka dengan as”Pakai keyword as untuk melakukan casting (mengubah) satu tipe angka ke tipe angka lain:
fn main() { let x: i32 = 10; let y: f64 = x as f64; // i32 -> f64
println!("{y}");}Ini lebih penting daripada kelihatannya. Coba bagi dua bilangan bulat tanpa casting, dan kamu akan mendapat pembagian bilangan bulat, bukan hasil desimal yang mungkin kamu harapkan:
fn main() { let a = 10; let b = 3;
println!("{}", a / b); // 3 (pembagian bilangan bulat) println!("{}", a as f64 / b as f64); // 3.3333333333333335}Casting ke tipe lebih kecil bisa kehilangan data
Section titled “Casting ke tipe lebih kecil bisa kehilangan data”Casting dari tipe yang lebih besar ke yang lebih kecil (misalnya i32 ke u8) tidak akan gagal. Nilainya hanya dipotong, dan hasilnya bisa mengejutkan:
fn main() { let big: i32 = 300; let small = big as u8; // u8 hanya bisa menampung 0-255 println!("{small}"); // 44, bukan 300: nilainya berputar (wrap around)}Casting float, karakter, dan boolean
Section titled “Casting float, karakter, dan boolean”as bisa dipakai untuk beberapa tipe lain selain bilangan bulat. Masing-masing punya aturan yang perlu kamu tahu:
fn main() { println!("{}", 3.99_f64 as i32); // 3: desimalnya dibuang println!("{}", -3.99_f64 as i32); // -3: dipotong ke arah nol, bukan ke bawah println!("{}", 3.99_f64.round() as i32); // 4: bulatkan dulu kalau itu yang kamu mau println!("{}", 300.0_f64 as u8); // 255: terlalu besar, jadi berhenti di nilai maksimum println!("{}", -5.0_f64 as u8); // 0: terlalu kecil, jadi berhenti di nilai minimum println!("{}", 'A' as u32); // 65: nomor kode sebuah char println!("{}", 97_u8 as char); // a: dan kembali lagi println!("{}", true as i32); // 1 (false akan menjadi 0)}Output:
3-34255065a1Beberapa hal yang bisa kamu ambil dari sini:
- Float ke bilangan bulat membuang semua angka di belakang koma. Nilainya tidak dibulatkan. Panggil
.round()dulu kalau kamu ingin bilangan bulat terdekat. - Float di luar rentang ditahan (clamp) ke nilai terdekat yang masih muat (
300.0menjadi255diu8). Ini berbeda dengan bilangan bulat, yang nilainya berputar (300menjadi44di contoh sebelumnya). - Karakter punya angka di baliknya (code point Unicode-nya).
'A' as u32menghasilkan65. Hanyau8yang bisa di-cast langsung kembali menjadichar. Untuk angka yang lebih besar, kamu memakaichar::from_u32, karena tidak semua angka adalah karakter yang valid. - Boolean berubah menjadi
1atau0. Arah sebaliknya tidak bisa:1 as booltidak akan bisa dikompilasi. Pakai perbandingan sepertin != 0sebagai gantinya.
Mengubah string menjadi angka
Section titled “Mengubah string menjadi angka”Casting dengan as hanya bisa dipakai antartipe angka. Untuk mengubah teks menjadi angka, misalnya sesuatu yang diketik pengguna, pakai .parse():
fn main() { let text = "42"; let number: i32 = text.parse().expect("bukan angka yang valid");
println!("{}", number + 8);}Output:
50.parse() bisa gagal (bagaimana kalau teksnya sama sekali bukan angka?), jadi yang dikembalikan adalah sebuah Result, bukan langsung angkanya. Kita belum membahas Result. Untuk sekarang, .expect("pesan") adalah cara sederhana untuk bilang “crash dengan pesan ini kalau gagal.” Cara yang benar untuk menanganinya akan kamu lihat di halaman Result.
Mengubah angka menjadi string
Section titled “Mengubah angka menjadi string”Arah sebaliknya lebih sederhana. Hampir semua tipe bisa diubah menjadi String dengan .to_string():
fn main() { let number = 42; let text = number.to_string(); println!("{}", text + "!");}Latihan
Section titled “Latihan”1. Nilai rata-rata
Section titled “1. Nilai rata-rata”Simpan tiga nilai ujian sebagai i32: 7, 8, dan 10. Tampilkan jumlahnya, lalu rata-ratanya dengan dua angka di belakang koma. Petunjuk: kalau kamu membagi dua bilangan bulat, hasilnya 8, bukan 8.33, jadi cast jumlahnya ke f64 lebih dulu. {:.2} menampilkan dua angka desimal.
Lihat solusi
fn main() { let a: i32 = 7; let b: i32 = 8; let c: i32 = 10;
let sum = a + b + c; let average = sum as f64 / 3.0; // 25.0 / 3.0, bukan 25 / 3
println!("jumlah: {sum}"); println!("rata-rata: {:.2}", average);}Output:
jumlah: 25rata-rata: 8.332. Harga dari teks
Section titled “2. Harga dari teks”Sebuah toko memberimu harga dalam bentuk teks, "4.50", dan jumlah barang sebagai i32, yaitu 3. Ubah teksnya menjadi f64, kalikan dengan jumlah barang, lalu tampilkan Total: 13.5. Petunjuk: kamu butuh kedua alat dari halaman ini: .parse() untuk teksnya dan as f64 untuk jumlah barangnya.
Lihat solusi
fn main() { let price_text = "4.50"; let quantity: i32 = 3;
let price: f64 = price_text.parse().expect("bukan harga yang valid"); let total = price * quantity as f64; // f64 * f64
println!("Total: {total}");}Output:
Total: 13.5Tanpa as f64, Rust akan menolak mengalikan f64 dengan i32, karena Rust tidak pernah mencampur tipe angka untukmu.
Ringkasan
Section titled “Ringkasan”- Rust tidak pernah mengonversi tipe secara otomatis. Kamu selalu melakukan casting secara eksplisit.
- Pakai
asuntuk mengonversi antartipe angka:x as f64,x as u8. - Casting ke tipe yang lebih kecil memotong nilai secara diam-diam. Tidak ada error, jadi hati-hati.
- Float ke bilangan bulat membuang desimalnya (pakai
.round()dulu untuk membulatkan).chardanbooljuga bisa di-cast ke angka. - Pakai
.parse()untuk mengubah teks menjadi angka, dan.to_string()untuk arah sebaliknya.
Kuis singkat
Section titled “Kuis singkat”Kuis singkat
1. Apa yang terjadi kalau kamu membagi dua bilangan bulat seperti 10 / 3 di Rust tanpa casting?
2. Apa yang terjadi kalau kamu melakukan casting 300_i32 as u8?
3. Apa yang dikembalikan .parse() saat mengubah string menjadi angka, mengingat konversinya bisa gagal?
Skor: 0 / 3
Bacaan lebih lanjut
Section titled “Bacaan lebih lanjut”- Casting — Rust by Example (bahasa Inggris): banyak contoh casting dengan
asyang bisa dijalankan, dengan komentar tentang hasil persis masing-masing. - Type cast expressions — The Rust Reference (bahasa Inggris): tabel lengkap casting apa saja yang diizinkan dan aturan persis untuk masing-masing.
- To and from Strings — Rust by Example (bahasa Inggris):
.to_string()dan.parse()dengan pembahasan sedikit lebih dalam. TryFrom— dokumentasi standard library (bahasa Inggris): konversi yang dicek (u8::try_from(...)) untuk dipakai saat sebuah nilai mungkin tidak muat.- Numeric Types — The Rust Reference (bahasa Inggris): ukuran dan rentang setiap tipe bilangan bulat dan float.