Loop, While, For — Rust

Looping di Rust Rust punya 3 jenis loop: loop, while, dan for. loop — Infinite Loop let mut counter = 0; loop { counter += 1; if counter == 5 { break; //…

Perulangan (loop) menjalankan blok kode yang sama berkali-kali. Rust punya tiga bentuk: loop, while, dan for. Bayangin dapur Kedai Martabak Bang Rusdi waktu ramai. Koki membuat martabak telur satu demi satu, dan langkahnya selalu sama: pecahkan 3 telur, adon, goreng. Yang beda cuma cara dia tahu kapan berhenti. "Terus bikin sampai aku bilang stop" itu loop. "Bikin selama telurnya masih cukup" itu while. "Bikin satu untuk tiap meja, meja 1 sampai 3" itu for.

🧪 Tebakan cepat: Bang Rusdi ingin mencetak tiga baris porsi dengan for porsi in 1..3 { println!("Porsi ke-{}", porsi); }. Berapa baris yang tercetak? Tebak dulu, jawabannya ada di bagian "for dan range".

loop: ulangi sampai break

Berapa martabak telur yang bisa dibuat dari stok 250 butir, kalau satu martabak memakai 3 butir?

fn main() {
    let mut stok_telur: u32 = 250;
    let mut jumlah = 0;
    let dibuat = loop {
        if stok_telur < 3 {
            break jumlah;
        }
        stok_telur -= 3;
        jumlah += 1;
    };
    println!("Martabak telur dibuat: {}", dibuat);
    println!("Sisa telur: {}", stok_telur);
}
Martabak telur dibuat: 83
Sisa telur: 1

while: selama kondisinya benar

Sekarang stoknya cuma 10 butir, dan tiap pesanan dicetak:

fn main() {
    let mut stok_telur = 10;
    let mut pesanan = 0;
    while stok_telur >= 3 {
        stok_telur -= 3;
        pesanan += 1;
        println!("Pesanan {}: sisa telur {}", pesanan, stok_telur);
    }
    println!("Sisa telur: {}", stok_telur);
}
Pesanan 1: sisa telur 7
Pesanan 2: sisa telur 4
Pesanan 3: sisa telur 1
Sisa telur: 1
Putaran Cek stok_telur >= 3 stok_telur sesudahnya pesanan
1 10 >= 3, benar 7 1
2 7 >= 3, benar 4 2
3 4 >= 3, benar 1 3
4 1 >= 3, salah: berhenti 1 3
error: Rust has no postfix increment operator
 --> src/main.rs:6:16
  |
6 |         pesanan++;
  |                ^^ not a valid postfix operator
  |
help: use `+= 1` instead
  |
6 -         pesanan++;
6 +         pesanan += 1;
  |

for dan range

fn main() {
    for porsi in 1..=3 {
        println!("Porsi ke-{}", porsi);
    }
    for porsi in 1..3 {
        println!("Porsi ke-{}", porsi);
    }
}
Porsi ke-1
Porsi ke-2
Porsi ke-3
Porsi ke-1
Porsi ke-2

for di atas array: nilai atau pinjaman

for juga bisa mengambil isi array satu per satu:

fn main() {
    let harga = [32000, 38000, 5000];
    let mut total = 0;
    for h in harga {
        total += h;
    }
    println!("Total: {}", total);
    for (i, h) in harga.iter().enumerate() {
        println!("{}: {}", i, h);
    }
}
Total: 75000
0: 32000
1: 38000
2: 5000

.iter().enumerate() memberi pasangan (nomor urut, isi), mulai dari 0. Untuk angka, for h in harga aman dipakai berulang, karena tiap angka disalin. Teks String beda: ia dipindah, seperti nota pesanan yang pindah ke dapur di pelajaran pertama.

fn main() {
    let antrean = [String::from("Martabak manis"), String::from("Martabak telur")];
    for pesanan in antrean {
        println!("Dimasak: {}", pesanan);
    }
    println!("Antrean: {}", antrean.len());
}
error[E0382]: borrow of moved value: `antrean`
 --> src/main.rs:6:29
  |
2 |     let antrean = [String::from("Martabak manis"), String::from("Martabak telur")];
  |         ------- move occurs because `antrean` has type `[String; 2]`, which does not implement the `Copy` trait
3 |     for pesanan in antrean {
  |                    ------- `antrean` moved due to this implicit call to `.into_iter()`
...
6 |     println!("Antrean: {}", antrean.len());
  |                             ^^^^^^^ value borrowed here after move
  |
help: consider iterating over a slice of the `[String; 2]`'s content to avoid moving into the `for` loop
  |
3 |     for pesanan in &antrean {
  |                    +

for pesanan in antrean memindahkan tiap nota ke pesanan, jadi setelah loop antrean sudah kosong. Saran compiler-nya tepat: for pesanan in &antrean cuma meminjam tiap nota. Dengan &, programnya mencetak Dimasak: Martabak manis, Dimasak: Martabak telur, lalu Antrean: 2.

break, continue, dan label

continue melompati sisa putaran ini dan lanjut ke putaran berikutnya. for meja in 1..=5 dengan if meja == 3 { continue; } mengantar ke meja 1, 2, 4, 5.

Loop di dalam loop butuh hati-hati: break biasa cuma keluar dari loop terdalam. Untuk keluar dari semuanya sekaligus, beri loop luar sebuah label:

fn main() {
    let mut stok_telur = 7;
    'pesanan: for meja in 1..=3 {
        for porsi in 1..=2 {
            if stok_telur < 3 {
                println!("Telur habis di meja {} porsi {}", meja, porsi);
                break 'pesanan;
            }
            stok_telur -= 3;
            println!("Meja {} porsi {}: sisa telur {}", meja, porsi, stok_telur);
        }
    }
}
Meja 1 porsi 1: sisa telur 4
Meja 1 porsi 2: sisa telur 1
Telur habis di meja 2 porsi 1

⚠️ Jebakan yang sering ketemu

TL;DR: loop mengulang terus sampai break, dan break nilai; membuat loop menghasilkan nilai (let dibuat = loop { ... };). while kondisi { } mengecek kondisi bool sebelum tiap putaran, jadi variabelnya harus berubah di dalam. for x in 1..=3 termasuk 3, for x in 1..3 berhenti di 2 (0..3 jalan tiga kali). for h in harga mengambil isi array, tapi untuk String isinya dipindah: pakai &antrean untuk meminjam. continue melompati satu putaran, break keluar dari loop terdalam, dan break 'label; keluar dari loop yang diberi label. Rust gak punya ++: tulis += 1.

Yang akan kamu pelajari