Loops and Ranges
for, while, and the range expressions (1..10, downTo, step) that make Kotlin's loops read like plain English.
អាន 2 នាទី
Kotlin has the loops you'd expect — for and while — but its for loop is built entirely around iterating over something, rather than the C-style "initialize, check, increment" header. Ranges are what usually supply that "something."
Ranges
A range expresses a sequence of values between two bounds, using ..:
val oneToFive = 1..5
for (i in oneToFive) {
print("$i ") // 1 2 3 4 5
}You rarely name a range first — it's far more common to write it inline:
for (i in 1..5) {
print("$i ") // 1 2 3 4 5
}1..5 is inclusive on both ends. To exclude the upper bound, use until:
for (i in 1 until 5) {
print("$i ") // 1 2 3 4
}Count backward with downTo, and skip values with step:
for (i in 10 downTo 1 step 2) {
print("$i ") // 10 8 6 4 2
}for over collections
The same for ... in syntax iterates over any collection, not just numeric ranges:
val languages = listOf("Kotlin", "Swift", "Rust")
for (language in languages) {
println(language)
}Need the index too? withIndex() pairs each element with its position:
for ((index, language) in languages.withIndex()) {
println("$index: $language")
}while and do-while
while and do-while work the way they do in most languages — while checks its condition before the first iteration, do-while checks after, guaranteeing at least one run:
var attempts = 0
while (attempts < 3) {
println("Attempt ${attempts + 1}")
attempts++
}
do {
println("This runs at least once")
} while (false)break and continue
Both work as you'd expect, and both can be labeled for jumping out of an outer loop from inside a nested one:
outer@ for (i in 1..3) {
for (j in 1..3) {
if (j == 2) continue@outer
println("i=$i, j=$j")
}
}Why ranges instead of a C-style for
A traditional for (int i = 0; i < 10; i++) gives you three separate places to make an off-by-one mistake: the initial value, the condition, and the increment, all written separately and all needing to agree with each other. A range like 0 until 10 states the exact same intent as a single, self-contained expression — there's no way for the "start," "end," and "step" to drift out of sync, because they're not three statements to keep consistent, just one.
With branching and looping covered, the next section moves to functions — where Kotlin's default arguments and lambdas start to make a real difference in how concise everyday code can be.