Dari semua bentuk perulangan di Rust, for adalah yang paling sering muncul dalam kode sehari-hari. Alasannya sederhana: mayoritas perulangan bekerja di atas urutan yang sudah diketahui — mencetak angka 1 sampai 10, memeriksa setiap harga menu pada sebuah array, atau mengisi baris tabel perkalian. Rust tidak memiliki bentuk for (i = 0; i < n; i++) seperti C; sebagai gantinya, Rust memakai idiom for x in <urutan> yang membaca seperti kalimat: “untuk setiap x di dalam urutan, jalankan blok ini”. Pada Chapter ini kita akan mempelajari Range sebagai penghasil urutan angka, iterasi array, dan perulangan bersarang.
Rentang Angka dengan Range #
Range adalah tipe bawaan Rust yang merepresentasikan deretan angka berurutan. Dua bentuknya sering tertukar oleh pemula: 1..4 berarti “mulai dari 1, berhenti sebelum 4” sehingga berisi 1, 2, 3; sedangkan 1..=4 berisi 1, 2, 3, 4 karena nilai akhir ikut disertakan. Saat for bertemu Range, Rust mengambil nilai-nilai tersebut satu per satu dari awal hingga akhir, mengikat tiap nilai ke variabel perulangan, lalu menjalankan blok kode untuk tiap nilai. Mari kita mulai dari contoh paling sederhana:
fn main() {
for number in 1..=5 {
println!("Iterasi ke-{}", number);
}
}Output yang Dihasilkan:
Iterasi ke-1
Iterasi ke-2
Iterasi ke-3
Iterasi ke-4
Iterasi ke-5Mari kita telaah baris-baris kode di atas:
- Baris 2 (
for number in 1..=5 {): Range1..=5menghasilkan angka1sampai5termasuk nilai akhir; variabelnumbermengikat satu nilai dari Range pada setiap iterasi. - Baris 3 (
println!("Iterasi ke-{}", number);): macroprintln!mencetak nilainumbersaat ini; blok ini berjalan tepat lima kali. - Setelah nilai
5selesai diproses, Range kehabisan nilai, perulangan berakhir, dan eksekusi berlanjut setelah blokfor.
Perbedaan dua titik versus dua titik sama dengan paling mudah dilihat ketika keduanya diletakkan berdampingan:
fn main() {
println!("Rentang 1..4 berisi:");
for number in 1..4 {
println!("- {}", number);
}
println!("Rentang 1..=4 berisi:");
for number in 1..=4 {
println!("- {}", number);
}
}Output yang Dihasilkan:
Rentang 1..4 berisi:
- 1
- 2
- 3
Rentang 1..=4 berisi:
- 1
- 2
- 3
- 4Perulangan pertama mencetak tiga angka karena 1..4 berhenti sebelum 4, sedangkan perulangan kedua mencetak empat angka karena 1..=4 menyertakan 4 sebagai nilai terakhir. Kebiasaan yang baik: gunakan .. ketika nilai akhir adalah batas (misalnya panjang array), dan gunakan ..= ketika nilai akhir adalah angka terakhir yang ingin diproses (misalnya nomor kursi 1 sampai 30).
Iterasi Array dengan for #
for tidak terbatas pada angka; setiap nilai yang dapat dijadikan urutan dapat diiterasi, dan array adalah contoh paling dekat dengan data nyata. Ketika for mengiterasi sebuah array, setiap elemen diambil satu per satu dari kiri ke kanan dan diikat ke variabel perulangan, sehingga kita tidak perlu mengurus indeks manual:
fn main() {
let menu_prices = [15000, 25000, 30000];
for price in menu_prices {
println!("Harga menu: Rp{}", price);
}
}Output yang Dihasilkan:
Harga menu: Rp15000
Harga menu: Rp25000
Harga menu: Rp30000Mari kita bedah program di atas:
- Baris 2 (
let menu_prices = [15000, 25000, 30000];): array bertipe[i32; 3]berisi tiga harga menu warung dibuat; tipe dan panjangnya diinferensi dari isinya. - Baris 4 (
for price in menu_prices {): variabelpricemengikat elemen array satu per satu — pertama15000, lalu25000, terakhir30000. - Baris 5 (
println!("Harga menu: Rp{}", price);): setiap harga dicetak tanpa perlu indeks, tanpacounter, dan tanpa risiko salah batas bawah atau batas atas.
Bandingkan dengan padanan while yang harus mengelola variabel penghitung dan mengakses elemen lewat indeks: setiap elemen tambahan pada kebutuhan while menambah satu tempat potensi galat. for memindahkan urusan batas tersebut ke mekanisme bahasa sehingga tidak mungkin mengakses elemen di luar jangkauan — perulangan berhenti otomatis tepat setelah elemen terakhir.
Satu perilaku penting yang perlu kita sadari: variabel perulangan adalah pengikat baru (binding) yang lahir dan mati di dalam satu iterasi. Ketika iterasi berpindah dari 15000 ke 25000, variabel price tidak “diubah” — pengikat lama berakhir dan pengikat baru dibuat untuk elemen berikutnya. Karena itu variabel perulangan tidak perlu ditandai mut, dan nilai yang tersimpan di variabel lain di luar blok tidak terpengaruh oleh perputaran iterasi.
Perulangan Bersarang #
Ketika sebuah for berada di dalam blok for lain, kita mendapatkan perulangan bersarang: untuk tiap nilai perulangan luar, perulangan dalam menjalankan seluruh putarannya dari awal. Pola ini cocok untuk kombinasi dua dimensi seperti tabel perkalian:
fn main() {
for row in 1..=3 {
for column in 1..=3 {
let product = row * column;
println!("{} x {} = {}", row, column, product);
}
}
}Output yang Dihasilkan:
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9Mari kita uraikan cara kerjanya:
- Baris 2 (
for row in 1..=3 {): perulangan luar mengikatrowbernilai1, lalu2, lalu3; setiap nilairowmemicu satu putaran penuh perulangan dalam. - Baris 3 (
for column in 1..=3 {): untukrow = 1, variabelcolumnberjalan dari1sampai3, menghasilkan tiga baris pertama pada output. - Baris 4 (
let product = row * column;): hasil kalirowdancolumndisimpan ke variabel lokalproductpada setiap kombinasi. - Baris 5 (
println!("{} x {} = {}", row, column, product);): baris ini berjalan3 x 3 = 9kali — angka iterasi bertambah secara perkalian, bukan penjumlahan, sehingga perulangan bersarang perlu dijaga jumlah tingkatnya.
Memilih for untuk Perulangan Terhitung #
Kekuatan for muncul ketika data atau batas perulangan sudah tersedia: panjang daftar, batas atas angka, atau isi array. Tabel berikut memetakan beberapa kebutuhan perulangan ke bentuk idiomatiknya:
| Kebutuhan | Bentuk yang tepat |
|---|---|
| Cetak angka 1 sampai 100 | for number in 1..=100 |
| Proses setiap elemen array | for item in items |
| Ulangi selama stok masih cukup | while stock >= minimum |
| Coba ulang sampai berhasil | loop dengan break |
Ringkasan #
for x in <urutan> adalah bentuk perulangan idiomatik Rust untuk data yang batasnya sudah diketahui. Range menyediakan dua notasi yang perlu dibedakan dengan cermat: start..end tidak menyertakan nilai akhir, sedangkan start..=end menyertakannya. Array diiterasi elemen demi elemen tanpa pengelolaan indeks manual, dan for dapat disarangkan untuk kombinasi dua dimensi. Selanjutnya kita akan mempelajari dua kata kunci yang mengendalikan laju perulangan: break dan continue.