Perulangan

Perulangan for dengan range dan collection, while, serta do-while.

Daftar isi

Perulangan menjalankan blok kode yang sama beberapa kali tanpa menyalin perintahnya. Kotlin menyediakan for untuk iterasi atas range dan collection, serta while dan do-while untuk perulangan yang dikendalikan kondisi. Topik ini membahas ketiganya beserta break, continue, dan label untuk perulangan bersarang. Seluruh contoh dirangkai dalam satu program utuh yang dijalankan dengan kotlinc.

for dengan range#

for pada Kotlin selalu beriterasi atas sesuatu, dan bentuk yang paling sering dipakai adalah range, yaitu rentang angka yang dibuat dengan operator ... Pernyataan for (i in 1..5) mengulang bloknya untuk nilai 1 sampai 5, dan kedua ujung rentang termasuk. Variabel perulangan i bersifat hanya-baca, sehingga penugasan kepadanya ditolak compiler.

Rentang dapat diatur lebih halus dengan tiga kata kunci pembantu. Kata kunci until mengeluarkan ujung atas, sehingga 1 until 5 menghasilkan 1 sampai 4. Kata kunci downTo membalik arah iterasi, dan step menentukan lompatannya, sehingga 5 downTo 1 step 2 menghasilkan 5, 3, dan 1. Kombinasi ketiganya mencakup kebutuhan penghitungan mundur, langkah tetap, dan rentang setengah terbuka. Rentang yang dibuat .. untuk bilangan bulat bertipe IntRange, dan rentang boleh pula disimpan ke dalam variabel bila ingin dipakai ulang. Batasnya tidak harus berupa angka tulisan, misalnya 1..batas dengan batas yang baru diketahui saat program berjalan. Nama variabel perulangan bebas dipilih, dan i hanyalah kebiasaan umum untuk penghitung.

for dengan collection#

Range bukan satu-satunya yang dapat diiterasi. for menerima collection apa pun yang dapat dilalui, misalnya List untuk daftar nama. Setiap putaran menaruh satu elemen ke variabel perulangan, sehingga kode yang sama bekerja untuk daftar dengan panjang berapa pun. Elemen yang ditaruh ke variabel perulangan juga bersifat hanya-baca, sama seperti variabel pada iterasi range.

kotlin Contoh: iterasi dengan indeks
// tidak-dijalankan
val piket = listOf("Ali", "Budi", "Citra")
for (i in piket.indices) {
    println("${i + 1}. ${piket[i]}")
}

Bentuk di atas memakai properti indices, yaitu range indeks yang sah untuk daftar tersebut, kemudian mengambil elemen lewat indeksnya. Pola ini berguna ketika nomor urut memang dibutuhkan. Apabila hanya elemennya yang diperlukan, iterasi langsung atas elemen lebih ringkas dan tidak menimbulkan risiko indeks melewati batas. Collection lain seperti Set diiterasi dengan cara yang sama. Karena setiap putaran hanya menyediakan satu elemen, tidak ada indeks yang dikelola manual, sehingga kelas error indeks melewati batas yang lazim terjadi pada perulangan dengan penghitung manual tidak muncul di sini. Iterasi yang sama juga bekerja untuk String, yaitu per karakter, bila isi teks perlu diproses satu per satu.

while dan do-while#

while memeriksa kondisi sebelum setiap putaran dan berhenti begitu kondisinya bernilai false. Bentuk ini cocok ketika jumlah putaran tidak diketahui di awal, misalnya mengulang sampai suatu keadaan tercapai. Variabel yang dipakai pada kondisi harus dideklarasikan dengan var dan diperbarui di dalam badan, karena tanpa pembaruan kondisi tidak akan pernah berubah.

do-while membalik urutannya, yaitu badan dijalankan lebih dahulu, lalu kondisi diperiksa. Akibatnya, badan do-while dijamin tereksekusi minimal satu kali, sesuai untuk pola coba terlebih dahulu lalu periksa seperti penghitung percobaan. Perhatikan bahwa do-while ditutup tanda titik koma setelah kurung kondisinya, dan tanda itu adalah bagian dari sintaks konstruksi ini. Kedua bentuk ini membutuhkan variabel var karena isinya berubah setiap putaran, berbeda dari variabel perulangan for yang diurus otomatis. Jumlah putarannya pun tidak harus diketahui di awal, cukup syarat berhentinya.

break dan continue#

Kata kunci break menghentikan perulangan terdalam yang melingkupinya, sedangkan continue membatalkan putaran yang sedang berjalan dan melompat ke putaran berikutnya. Keduanya memangkas pekerjaan yang tidak perlu, misalnya melewati nilai yang tidak relevan atau berhenti begitu jawaban ditemukan.

Pada perulangan bersarang, break dan continue tanpa label menunjuk perulangan terdalam. Label mengubah sasarannya. Nama label bebas dipilih, tetapi kata yang menunjuk perulangan luarnya, misalnya luar atau baris, membuat rujukan break@ dan continue@ tetap terbaca. Label ditulis di depan perulangan luar, misalnya luar@, lalu dirujuk sebagai break@luar untuk keluar dari kedua tingkat sekaligus.

kotlin Contoh: continue berlabel pada perulangan bersarang
// tidak-dijalankan
luar@ for (baris in 1..3) {
    for (kolom in 1..3) {
        if (kolom == 2) continue@luar
        print("($baris,$kolom) ")
    }
}

Pada contoh tersebut, continue@luar membatalkan seluruh baris begitu kolom bernilai 2, bukan hanya kolom itu. Tanpa label, continue akan melanjutkan ke kolom berikutnya saja dan baris tetap berlanjut.

Program contoh: semua bentuk dalam satu berkas#

Berkas main.kt berikut merangkai seluruh bentuk perulangan yang telah dibahas, mulai dari range, collection, while, do-while, hingga break, continue, dan label. Programnya sengaja berhingga, yaitu setiap perulangan memiliki batas yang pasti tercapai. Setiap blok ditandai komentar dan diakhiri println(), sehingga keluaran tiap blok terbaca sebagai baris terpisah.

kotlin main.kt
fun main() {
    // for dengan range naik
    for (i in 1..5) {
        print("$i ")
    }
    println()

    // for dengan until, downTo, dan step
    for (i in 1 until 5) {
        print("$i ")
    }
    println()
    for (i in 5 downTo 1 step 2) {
        print("$i ")
    }
    println()

    // for dengan collection
    val piket = listOf("Ali", "Budi", "Citra")
    for (nama in piket) {
        print("$nama ")
    }
    println()

    // while dengan penghitung turun
    var sisa = 3
    while (sisa > 0) {
        print("$sisa ")
        sisa--
    }
    println("Selesai!")

    // do-while berhingga
    var percobaan = 1
    do {
        print("percobaan-$percobaan ")
        percobaan++
    } while (percobaan <= 3)
    println()

    // break dan continue
    for (i in 1..10) {
        if (i == 3) continue
        if (i == 6) break
        print("$i ")
    }
    println()

    // break berlabel pada perulangan bersarang
    luar@ for (baris in 1..3) {
        for (kolom in 1..3) {
            if (kolom == 3) break@luar
            print("($baris,$kolom) ")
        }
    }
    println()
}

Kompilasi dan jalankan dengan perintah berikut. Jalur instalasi kotlinc mengikuti lingkungan kerja modul ini dan perlu disesuaikan dengan lokasi instalasi pada komputer lain.

bash
# siapkan alat kompilasi Kotlin pada lingkungan kerja ini
export PATH=/home/kal/my-project/tools/kotlinc/bin:/home/kal/my-project/tools/jdk-merged/bin:$PATH
export STDLIB=/home/kal/my-project/tools/kotlinc/lib/kotlin-stdlib.jar

# kompilasi main.kt menjadi out.jar, lalu jalankan kelas MainKt
kotlinc main.kt -d out.jar && java -cp "out.jar:$STDLIB" MainKt
text Keluaran
1 2 3 4 5 
1 2 3 4 
5 3 1 
Ali Budi Citra 
3 2 1 Selesai!
percobaan-1 percobaan-2 percobaan-3 
1 2 4 5 
(1,1) (1,2) 

Delapan baris keluaran masing-masing berasal dari satu blok program. Tiga baris pertama menunjukkan 1..5, 1 until 5, dan 5 downTo 1 step 2. Baris keempat adalah iterasi atas List, sedangkan baris kelima dan keenam adalah while dan do-while. Baris ketujuh memperlihatkan continue yang melompati angka 3 dan break yang berhenti di angka 6. Baris kedelapan membuktikan break@luar menghentikan kedua tingkat perulangan begitu kolom bernilai 3. Bila salah satu blok diubah, angka pada keluaran berubah mengikuti rentang atau batas yang ditulis, sehingga program ini juga cocok untuk uji coba kecil.

Kesalahan umum#

Kesalahan pertama adalah salah ujung rentang. Rentang 1..5 memuat lima angka, sedangkan 1 until 5 memuat empat. Kebiasaan menukar keduanya menimbulkan off-by-one, yaitu selisih satu pada jumlah putaran. Pilih .. apabila ujung atas ikut diproses, dan until apabila tidak.

Kesalahan kedua adalah menugaskan nilai ke variabel perulangan for. Variabel itu dideklarasikan otomatis dan tidak dapat diubah, sehingga i = i + 1 di dalam badan ditolak compiler. Apabila pola penambahan manual memang dibutuhkan, gunakan while dengan variabel var.

Kesalahan ketiga adalah mengira break keluar dari semua perulangan. Pada perulangan bersarang tanpa label, break hanya keluar dari tingkat terdalam, dan putaran luarnya tetap berjalan. Gunakan label apabila perulangan luarnya juga harus berhenti. Kesalahan terakhir adalah menukar arah pada downTo, misalnya mengharapkan 1 downTo 5 berjalan naik. Rentang yang arahnya tertukar tidak pernah dieksekusi dan tidak menimbulkan pesan error apa pun. Menguji rentang dengan nilai kecil terlebih dahulu mempercepat penemuan kesalahan semacam ini.

Ringkasan#

  • for mengiterasi range (1..5, until, downTo, step) dan elemen collection satu per satu.
  • while memeriksa kondisi sebelum badan, sedangkan do-while menjalankan badan minimal satu kali.
  • break menghentikan perulangan terdalam, continue melompat ke putaran berikutnya, dan label mengarahkan keduanya ke perulangan luar.
  • Setiap perulangan berbasis kondisi wajib memiliki jalur menuju kondisi false.

Referensi#