Banyak pekerjaan program bersifat berulang: menghitung ulang total keranjang setiap kali barang ditambahkan, terus mendengarkan permintaan dari pengguna, atau mencoba menyambungkan kembali jaringan ketika koneksi terputus. Ciri khas pekerjaan seperti ini adalah jumlah perulangannya tidak diketahui di awal — program berhenti ketika sebuah peristiwa terjadi, bukan ketika sebuah angka tercapai. Rust menyediakan kata kunci loop untuk kebutuhan tersebut: blok kode yang dijalankan tanpa henti sampai kita secara eksplisit memutuskan untuk keluar. Pada Chapter ini kita akan mempelajari cara mengendalikan loop dengan break, termasuk kemampuan khas Rust untuk keluar dari loop sambil membawa sebuah nilai hasil.
Sintaks Dasar loop #
Kata kunci loop diikuti satu blok kurung kurawal, tanpa kondisi apa pun. Ketika eksekusi program mencapai akhir blok, Rust tidak melanjutkan ke statement setelah blok, melainkan melompat kembali ke awal blok dan mengulang isi blok dari atas. Perulangan ini benar-benar tanpa henti (infinite loop), sehingga hampir setiap loop berguna selalu berisi break — kata kunci yang menghentikan perulangan dan melanjutkan eksekusi ke statement setelah blok loop. Mari kita lihat keduanya bekerja sama:
fn main() {
let mut counter = 0;
loop {
counter += 1;
println!("Iterasi ke-{}", counter);
if counter == 3 {
break;
}
}
println!("Perulangan selesai.");
}Output yang Dihasilkan:
Iterasi ke-1
Iterasi ke-2
Iterasi ke-3
Perulangan selesai.Mari kita telaah apa yang terjadi pada baris-baris kode di atas:
- Baris 2 (
let mut counter = 0;): variabelcounterdibuat dengan nilai awal0dan ditandaimutkarena nilainya akan diubah di dalam perulangan. - Baris 4 (
loop {): program memasuki blok perulangan tanpa henti; setelah baris terakhir blok tercapai, eksekusi kembali ke baris ini. - Baris 5 (
counter += 1;): nilaicounterbertambah satu pada setiap iterasi —1,2, lalu3. - Baris 6 (
println!("Iterasi ke-{}", counter);): macroprintln!mencetak nomor iterasi saat ini ke terminal. - Baris 8 (
if counter == 3 {): Rust membandingkan nilaicounterdengan3; perbandingan bernilaifalsepada dua iterasi pertama dan bernilaitruepada iterasi ketiga. - Baris 9 (
break;): pada iterasi ketiga,breakmenghentikan perulangan seketika dan melanjutkan eksekusi ke statement setelah blokloop. - Baris 13 (
println!("Perulangan selesai.");): baris ini hanya tercapai setelahbreakdieksekusi, yang membuktikan bahwalooptelah berakhir.
Keluar dengan break Bernilai #
Kemampuan khas Rust yang jarang ada di bahasa lain: loop sebenarnya adalah sebuah expression, jadi blok loop dapat menghasilkan nilai. Nilai tersebut ditentukan oleh break yang kita beri operand — penulisan break nilai; menghentikan perulangan sekaligus menjadikan nilai sebagai hasil dari keseluruhan loop. Hasil itu lalu dapat diikat ke variabel dengan let seperti nilai expression biasa. Mari kita gunakan pola ini untuk mencari kuadrat pertama yang mencapai 100:
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter * counter >= 100 {
break counter * counter;
}
};
println!("Kuadrat pertama yang >= 100: {}", result);
}Output yang Dihasilkan:
Kuadrat pertama yang >= 100: 100Mari kita uraikan cara kerja program di atas:
- Baris 4 (
let result = loop {): variabelresultsiap menampung hasil dari expressionloop; program masuk ke blok perulangan untuk menghitung nilai tersebut. - Baris 5 (
counter += 1;): counter naik satu per satu mulai dari1. - Baris 7 (
if counter * counter >= 100 {): setiap iterasi memeriksa apakah kuadrat daricountersudah mencapai100—1,4,9, dan seterusnya sampai100. - Baris 8 (
break counter * counter;): ketikacountermencapai10, hasil10 * 10adalah100sehingga kondisi terpenuhi;breakkeluar dari perulangan dan membawa nilai100sebagai hasil expressionloop. - Baris 10 (
};): titik koma di sini menutup statementlet result = loop ... ;— perhatikan bahwa titik koma berada setelah kurung kurawal penutup, bukan di dalam blok. - Baris 12 (
println!("Kuadrat pertama yang >= 100: {}", result);): nilairesultyang berisi100dicetak ke terminal.
Perhatikan perbedaan dua bentuk break yang sudah kita temui: break; keluar tanpa membawa nilai, sedangkan break counter * counter; keluar sambil membawa nilai. Keduanya sah; bentuk kedua hanya bermakna ketika hasil loop dipakai sebagai nilai. Kita akan banyak menemui pola let result = loop { ... break nilai; }; pada Chapter-Chapter selanjutnya, misalnya saat menunggu hasil operasi yang harus dicoba berkali-kali.
Pola Percobaan Ulang Koneksi #
Kekuatan loop paling terasa ketika kondisi berhenti muncul dari dalam proses itu sendiri, bukan dari hitungan di depan. Contoh klasiknya adalah percobaan ulang koneksi: program mencoba menyambung, memeriksa hasilnya, dan mengulang selama masih gagal. Karena jumlah percobaan sebelum berhasil tidak diketahui di awal, loop dengan break bernilai bool menjadi pilihan yang pas:
fn main() {
let mut attempts = 0;
let connected = loop {
attempts += 1;
println!("Percobaan koneksi ke server, nomor {}", attempts);
if attempts == 3 {
break true;
}
};
if connected {
println!("Server terhubung setelah {} percobaan.", attempts);
}
}Output yang Dihasilkan:
Percobaan koneksi ke server, nomor 1
Percobaan koneksi ke server, nomor 2
Percobaan koneksi ke server, nomor 3
Server terhubung setelah 3 percobaan.Mari kita bedah program di atas:
- Baris 2 (
let mut attempts = 0;): variabelattemptsmenghitung berapa kali program sudah mencoba menyambung. - Baris 4 (
let connected = loop {): hasil perulangan diikat ke variabelconnected; tipeconnectedditentukan oleh nilai yang dibawabreak, dalam contoh inibool. - Baris 5–6 (
attempts += 1;danprintln!(...)): setiap percobaan menaikkan penghitung lalu mencatat percobaan tersebut ke terminal. - Baris 8 (
if attempts == 3 {): program mensimulasikan koneksi yang berhasil pada percobaan ketiga; di program nyata, cabang ini biasanya memeriksa hasil fungsi koneksi sungguhan. - Baris 9 (
break true;): perulangan berakhir dan nilaitruemenjadi isi variabelconnected. - Baris 13 (
if connected {): kondisi bernilaitruesehingga program mencetak laporan jumlah percobaan yang memakai nilaiattemptsdari dalam perulangan.
Ringkasan #
Kata kunci loop menjalankan blok kode tanpa henti, dan break adalah satu-satunya jalan keluar yang kita tentukan sendiri. Rust memperlakukan loop sebagai expression, sehingga break nilai; dapat mengembalikan hasil dari perulangan dan mengikatnya ke variabel dengan let result = loop { ... };. Pola ini cocok untuk proses yang jumlah perulangannya tidak diketahui di awal seperti percobaan ulang koneksi. Selanjutnya kita akan mempelajari while, perulangan yang memeriksa kondisi sebelum setiap iterasi.