Aplikasi kasir menjumlahkan harga, mengalikan dengan jumlah, memotong diskon, lalu membandingkan total dengan batas minimal transaksi. Seluruh kegiatan itu digerakkan dua keluarga operator: aritmetika untuk menghitung dan perbandingan untuk menguji hubungan antar nilai. Keduanya terlihat sama dengan PHP, tetapi Rust membawa satu aturan ketat yang mengubah cara kita menulis: kedua operan harus bertipe persis sama, tanpa konversi otomatis sekecil apa pun. Pada Chapter ini kita akan menghitung dengan lima operator aritmetika, membedah perilaku pembagian integer, memakai operator perbandingan, dan mengalami langsung galat saat tipe operan berbeda.
Operator Aritmetika #
Rust menyediakan lima operator aritmetika dasar yang bekerja pada tipe integer dan floating point:
| Operator | Operasi | Contoh |
|---|---|---|
+ | penjumlahan | subtotal + ongkir |
- | pengurangan | total - diskon |
* | perkalian | harga * jumlah |
/ | pembagian | total / 2 |
% | sisa bagi (modulus) | total % 7 |
Kita langsung praktik menghitung struk belanja:
fn main() {
let harga_satuan = 15_000;
let jumlah = 4;
let ongkir = 25_000;
let subtotal = harga_satuan * jumlah;
let total = subtotal + ongkir;
let setelah_diskon = total - 5_000;
let bagi_rata = setelah_diskon / 2;
let sisa = setelah_diskon % 7;
println!("Subtotal: Rp{}", subtotal);
println!("Total: Rp{}", total);
println!("Setelah diskon: Rp{}", setelah_diskon);
println!("Bagi rata: Rp{}", bagi_rata);
println!("Sisa bagi: {}", sisa);
}Output yang Dihasilkan:
Subtotal: Rp60000
Total: Rp85000
Setelah diskon: Rp80000
Bagi rata: Rp40000
Sisa bagi: 4Mari kita bedah perhitungan pada tiap barisnya:
- Baris 6 (
let subtotal = harga_satuan * jumlah;): operator*mengalikan15000dengan4menghasilkan60000. - Baris 7 (
let total = subtotal + ongkir;): operator+menjumlahkan60000dengan ongkir25000menjadi85000. - Baris 8 (
let setelah_diskon = total - 5_000;): operator-memotong5000dari total sehingga tersisa80000. - Baris 9 (
let bagi_rata = setelah_diskon / 2;): operator/membagi80000dengan2menjadi40000. - Baris 10 (
let sisa = setelah_diskon % 7;): operator%mencari sisa80000dibagi7; karena7 x 11428 = 79996, sisanya adalah4.
Seluruh operan bertipe i32, sehingga setiap hasil juga i32 dan perhitungan berjalan mulus. Aturan tipe inilah yang menjadi fokus kita di bagian akhir chapter.
Pembagian Integer Memotong Angka Desimal #
Pembagian dua integer di Rust menghasilkan integer, dan bagian desimalnya dipotong lurus ke arah nol (truncation), bukan dibulatkan ke atas atau ke terdekat. Perilaku ini sering mengejutkan pemula yang mengharapkan hasil 2.85 dari 20 / 7. Kita buktikan dengan membagikan apel kepada anak-anak:
fn main() {
let jumlah_apel = 20;
let jumlah_anak = 7;
let apel_per_anak = jumlah_apel / jumlah_anak;
let apel_sisa = jumlah_apel % jumlah_anak;
println!("{} apel untuk {} anak", jumlah_apel, jumlah_anak);
println!("Setiap anak mendapat {} apel", apel_per_anak);
println!("Sisa {} apel untuk ibu", apel_sisa);
let pembagian_float = 20.0 / 7.0;
println!("Hasil pembagian float: {}", pembagian_float);
}Output yang Dihasilkan:
20 apel untuk 7 anak
Setiap anak mendapat 2 apel
Sisa 6 apel untuk ibu
Hasil pembagian float: 2.857142857142857Mari kita amati tiga hasil berbeda di atas:
- Baris 5 (
let apel_per_anak = jumlah_apel / jumlah_anak;):20 / 7secara matematis bernilai2.857..., tetapi karena kedua operan bertipe integer, hasilnya dipotong menjadi2. - Baris 6 (
let apel_sisa = jumlah_apel % jumlah_anak;): operator%melengkapi pembagian dengan sisa6; polahasil x pembagi + sisa = angka asliberlaku, yaitu2 x 7 + 6 = 20. - Baris 12 (
let pembagian_float = 20.0 / 7.0;): penulisan20.0dan7.0membuat kedua operan bertipe floating point, sehingga hasilnya mempertahankan angka desimal2.857142857142857.
Kombinasi / dan % pada integer adalah pola standar untuk membagikan barang secara adil, sedangkan pembagian desimal menuntut kedua operan ditulis sebagai floating point.
Operator Perbandingan #
Enam operator perbandingan menguji hubungan dua nilai dan selalu menghasilkan bool:
| Operator | Makna | Contoh hasil |
|---|---|---|
== | sama dengan | 25000 == 25000 menjadi true |
!= | tidak sama dengan | 20000 != 25000 menjadi true |
< | lebih kecil | 20000 < 25000 menjadi true |
> | lebih besar | 25000 > 20000 menjadi true |
<= | lebih kecil atau sama | 20000 <= 20000 menjadi true |
>= | lebih besar atau sama | 20000 >= 25000 menjadi false |
Kita bandingkan harga dua minuman di kedai:
fn main() {
let harga_kopi = 25_000;
let harga_teh = 20_000;
println!("Kopi > teh : {}", harga_kopi > harga_teh);
println!("Kopi = teh : {}", harga_kopi == harga_teh);
println!("Teh < kopi : {}", harga_teh < harga_kopi);
println!("Teh <= kopi: {}", harga_teh <= harga_kopi);
println!("Teh != kopi: {}", harga_teh != harga_kopi);
}Output yang Dihasilkan:
Kopi > teh : true
Kopi = teh : false
Teh < kopi : true
Teh <= kopi: true
Teh != kopi: trueSetiap ekspresi seperti harga_kopi > harga_teh dievaluasi menjadi true atau false, lalu nilai boolean itu dicetak langsung oleh println!. Nilai hasil perbandingan juga bisa disimpan ke variable bertipe bool dan dipakai sebagai kondisi if, yang akan kita manfaatkan di section Kontrol Alur.
Kedua Operan Harus Bertipe Sama #
Aturan paling khas Rust adalah larangan pencampuran tipe pada operasi aritmetika. PHP secara diam-diam mengonversi "5" + 3.5 menjadi 8.5; Rust menolak keras karena konversi senyap adalah sumber bug presisi yang sulit dilacak. Kode berikut mengalikan bilangan bulat dengan bilangan desimal:
fn main() {
let harga = 25_000;
let diskon = 0.1;
let harga_setelah_diskon = harga - harga * diskon;
println!("Harga setelah diskon: Rp{}", harga_setelah_diskon);
}Kompilasi gagal dengan inti pesan berikut:
error[E0277]: cannot multiply `{integer}` by `{float}`
--> main.rs:5:46
|
5 | let harga_setelah_diskon = harga - harga * diskon;
| ^ no implementation for `{integer} * {float}`
|
= help: the trait `Mul<{float}>` is not implemented for `{integer}`
error: aborting due to 1 previous errorRust kemudian menampilkan daftar panjang kombinasi tipe yang sah untuk perkalian, tetapi pesan intinya sudah jelas: operator * tidak memiliki implementasi untuk integer dikali float. Solusinya ada dua, dan keduanya membuat konversi terlihat telanjang di kode. Pertama, samakan tipe sejak awal dengan menulis let harga = 25_000.0; dan let diskon = 0.1; sehingga semuanya floating point. Kedua, konversikan eksplisit di titik perhitungan, misalnya harga as f64 * diskon, yang akan kita kuasai pada Chapter Konversi Tipe dengan as.
Ringkasan #
Lima operator aritmetika (+, -, *, /, %) bekerja pada integer dan floating point, dengan hasil pembagian integer yang dipotong ke arah nol dan sisa bagi yang tersedia lewat %. Enam operator perbandingan menghasilkan bool dan menjadi bahan baku kondisi. Batasan utama yang harus kita patuhi: kedua operan wajib bertipe persis sama karena Rust tidak melakukan konversi otomatis antar tipe. Selanjutnya kita melanjutkan ke operator logika dan bitwise yang mengoperasikan nilai kebenaran dan bit-bit data.