1. 简介
循环是编程语言中最基础的控制结构之一,它允许我们在满足特定条件时重复执行一段代码。
本文将系统介绍 Kotlin 支持的几种循环类型:
- ✅
repeat
- ✅
for
循环 - ✅
while
循环 - ✅
do..while
循环
我们从最简单的 repeat
开始讲起。对于有经验的开发者来说,这部分内容虽然基础,但在某些场景下非常实用,比如快速执行某段逻辑 N 次而无需手动维护计数器。
2. repeat 循环
repeat
是 Kotlin 中最简洁的循环形式,适用于明确知道执行次数的场景。
例如,打印两次 "Hello World":
repeat(2) {
println("Hello World")
}
更进一步,你还可以获取当前迭代的索引(从 0 开始):
repeat(2) { index ->
println("第 ${index + 1} 次:Hello World")
}
⚠️ 注意:repeat
的参数必须是非负整数,传入负数会抛出 IllegalArgumentException
—— 这是个容易踩坑的地方,调用前最好做校验。
3. for 循环
Kotlin 的 for
循环语法如下:
for (变量 in 表达式) {
// 执行语句
}
✅ 核心能力:for
可以遍历任何实现了 Iterable
接口的对象,包括范围(range)、数组、集合等。
3.1 遍历数值范围
Kotlin 中的 range 表达式非常强大,例如:
for (i in 1..5) {
println(i) // 输出 1 到 5
}
for (i in 1 until 5) {
println(i) // 输出 1 到 4,不包含 5
}
for (i in 10 downTo 1 step 2) {
println(i) // 输出 10, 8, 6, 4, 2
}
🔗 相关阅读:Kotlin Ranges
3.2 遍历数组
声明一个元音字母数组:
val vowels = arrayOf('a', 'e', 'i', 'o', 'u')
遍历元素:
for (vowel in vowels) {
println(vowel)
}
遍历索引:
for (index in vowels.indices) {
println(vowels[index])
}
更优雅的方式是使用 withIndex()
同时获取索引和值:
for ((index, vowel) in vowels.withIndex()) {
println("索引 $index 处的元音是:$vowel")
}
📌 原理说明:withIndex()
返回的是 IndexedValue
对象,通过解构声明(destructuring declaration)自动提取 component1()
(index)和 component2()
(value)。
🔗 深入理解:Kotlin 解构声明
3.3 遍历 List
List 是有序可重复的集合,遍历方式与数组类似:
val names = listOf("Alice", "Bob", "Charlie")
for (name in names) {
println(name)
}
也可以通过索引遍历:
for (i in names.indices) {
println("$i: ${names[i]}")
}
🔗 参考文档:Kotlin Lists - Loops 和 按索引遍历集合
3.4 遍历 Map
Map 存储键值对,遍历方式多样:
val capitalCityByCountry = mapOf(
"Netherlands" to "Amsterdam",
"Germany" to "Berlin",
"USA" to "Washington, D.C."
)
遍历每个 entry:
for (entry in capitalCityByCountry) {
println("首都 ${entry.value} 属于国家 ${entry.key}")
}
仅遍历 key 或 value:
// 遍历 key
for (country in capitalCityByCountry.keys) {
println(country)
}
// 遍历 value
for (capitalCity in capitalCityByCountry.values) {
println(capitalCity)
}
推荐使用解构声明直接获取 key 和 value:
for ((country, capitalCity) in capitalCityByCountry) {
println("国家 $country 的首都是 $capitalCity")
}
这种方式代码更清晰,也更符合 Kotlin 的函数式风格。
3.5 函数式遍历:forEach
除了传统的 for
循环,Kotlin 更推荐使用函数式风格的 forEach
:
names.forEach { name ->
println(name)
}
// 带索引的 forEach
names.forEachIndexed { index, name ->
println("$index: $name")
}
✅ 优势:链式调用友好,配合 filter
、map
等操作更简洁。
❌ 缺点:在 lambda 中使用 break
或 continue
会受限(需要标签),性能略低于原生 for
(但通常可忽略)。
🔗 进阶用法:Nested forEach in Kotlin
4. while 循环
while
循环在布尔表达式为 true
时持续执行:
var counter = 0
while (counter < 5) {
println("while 循环计数器: ${counter++}")
}
输出:0 到 4。
⚠️ 关键特性:先判断条件,再执行循环体。这意味着如果初始条件为 false
,循环体一次都不会执行:
while (false) {
println("这行永远不会输出")
}
无限循环写法:
while (true) {
println("我是一个无限循环")
}
实际开发中应避免死循环,除非配合外部中断逻辑(如线程控制)。
5. do..while 循环
do..while
与 while
的最大区别在于:先执行循环体,再判断条件。
语法:
do {
// 执行语句
} while (布尔表达式)
示例:
var counter = 0
do {
println("do..while 计数器: ${counter++}")
} while (counter < 5)
输出同样是 0 到 4。
✅ 核心优势:至少执行一次。即使条件一开始就不满足:
do {
println("这行一定会输出一次")
} while (false)
这个特性在需要“至少尝试一次”的场景下非常有用,比如用户输入验证。
6. return、break 与 continue
Kotlin 提供了三种结构化跳转表达式:
return
:退出当前函数break
:跳出当前循环continue
:跳过本次迭代,进入下一次
示例:
for (i in 1..10) {
if (i == 5) break // 结束循环
if (i % 2 == 0) continue // 跳过偶数
println(i) // 输出 1, 3
}
⚠️ 踩坑提醒:在一个循环中频繁使用多个 break
或 continue
是典型的 code smell(代码异味),会导致逻辑混乱,建议重构为更清晰的结构或提取成函数。
🔗 详细规则:Kotlin return, break, continue
7. 多变量循环
有时我们需要同时遍历多个序列,Kotlin 提供了优雅的解决方案。
7.1 使用 zip 操作符
假设有两个队伍进行配对比赛:
val teamA = listOf("A1", "A2", "A3")
val teamB = listOf("B1", "B2")
使用 zip
将两个列表按顺序配对,较短的列表决定最终长度:
fun showMatches(team1: List<String>, team2: List<String>) {
for ((player1, player2) in team1 zip team2) {
println("$player1 vs $player2")
}
}
调用 showMatches(teamA, teamB)
输出:
A1 vs B1
A2 vs B2
⚠️ 注意:teamA
的 A3
被自动忽略。
另一种思路:先合并再遍历:
fun showMatchLabels(team1: List<String>, team2: List<String>) {
val matches = team1.zip(team2) { p1, p2 -> "$p1 vs $p2" }
for (match in matches) {
println(match)
}
}
🔗 API 文档:Kotlin zip 函数
7.2 生成乘法表
结合 range 和 zip
生成指定区间的乘法表:
fun printMultiplicationTable(factor: Int, start: Int, end: Int) {
val multipliers = start..end
val results = (factor * start)..(factor * end) step factor
for ((multiplier, result) in multipliers zip results) {
println("$factor x $multiplier = $result")
}
}
测试:
printMultiplicationTable(27, 3, 7)
输出:
27 x 3 = 81
27 x 4 = 108
27 x 5 = 135
27 x 6 = 162
27 x 7 = 189
📌 技巧:results
是一个 progression(步进序列),步长为 factor
,这是实现的关键。
8. 总结
本文全面梳理了 Kotlin 的循环机制:
repeat
:固定次数执行,简洁明了for
:最常用,支持 range、数组、集合及解构while
:先判后执,可能一次都不执行do..while
:先执后判,至少执行一次- 多变量循环:善用
zip
实现优雅配对 - 跳转控制:合理使用
break
/continue
,避免过度嵌套
作为高级开发者,不仅要掌握语法,更要理解其适用场景和潜在陷阱。例如,在性能敏感的循环中优先使用原生 for
而非 forEach
;在需要解耦逻辑时考虑函数式风格。
✅ 最佳实践:优先选择表达力强且不易出错的语法(如 for
+ in
),避免过度使用跳转语句。
所有示例代码已整理至 GitHub:
https://github.com/baeldung/kotlin-tutorials/tree/master/core-kotlin-modules/core-kotlin-3