控制流
与其他编程语言一样,Kotlin 能够根据一段代码的求值结果是否为真来做出决策。这类代码称为条件表达式。Kotlin 还能够创建和遍历循环。
条件表达式
Kotlin 提供了 if
和 when
来检查条件表达式。
NOTE
如果你必须在 if
和 when
之间做出选择,我们推荐使用 when
,因为它:
使你的代码更易读。
使其更容易添加另一个分支。
减少代码中的错误。
if
要使用 if
,请将条件表达式放在括号 ()
内,并将当结果为真时要执行的操作放在大括号 {}
内:
fun main() {
val d: Int
val check = true
if (check) {
d = 1
} else {
d = 2
}
println(d)
// 1
}
Kotlin 中没有三元运算符 condition ? then : else
。相反,if
可以用作表达式。如果每个操作只有一行代码,则大括号 {}
是可选的:
fun main() {
val a = 1
val b = 2
println(if (a > b) a else b) // Returns a value: 2
}
when
当你的条件表达式有多个分支时,使用 when
。
要使用 when
:
- 将你要评估的值放在括号
()
内。 - 将分支放在大括号
{}
内。 - 在每个分支中使用
->
来分隔每个检查和当检查成功时要执行的操作。
when
既可以用作语句,也可以用作表达式。语句不返回任何内容,而是执行操作。
以下是使用 when
作为语句的示例:
fun main() {
val obj = "Hello"
when (obj) {
// Checks whether obj equals to "1"
"1" -> println("One")
// Checks whether obj equals to "Hello"
"Hello" -> println("Greeting")
// Default statement
else -> println("Unknown")
}
// Greeting
}
NOTE
请注意,所有分支条件都按顺序检查,直到其中一个被满足。因此,只有第一个合适的分支会被执行。
表达式返回一个值,该值可以在你的代码中稍后使用。
以下是使用 when
作为表达式的示例。该 when
表达式会立即赋值给一个变量,该变量随后与 println()
函数一起使用:
fun main() {
val obj = "Hello"
val result = when (obj) {
// If obj equals "1", sets result to "one"
"1" -> "One"
// If obj equals "Hello", sets result to "Greeting"
"Hello" -> "Greeting"
// Sets result to "Unknown" if no previous condition is satisfied
else -> "Unknown"
}
println(result)
// Greeting
}
到目前为止你所看到的 when
示例都带有一个主题:obj
。但 when
也可以不带主题使用。
此示例使用不带主题的 when
表达式来检查一系列布尔表达式:
fun main() {
val trafficLightState = "Red" // This can be "Green", "Yellow", or "Red"
val trafficAction = when {
trafficLightState == "Green" -> "Go"
trafficLightState == "Yellow" -> "Slow down"
trafficLightState == "Red" -> "Stop"
else -> "Malfunction"
}
println(trafficAction)
// Stop
}
但是,你可以编写相同的代码,只是将 trafficLightState
作为主题:
fun main() {
val trafficLightState = "Red" // This can be "Green", "Yellow", or "Red"
val trafficAction = when (trafficLightState) {
"Green" -> "Go"
"Yellow" -> "Slow down"
"Red" -> "Stop"
else -> "Malfunction"
}
println(trafficAction)
// Stop
}
带主题使用 when
可以使你的代码更易读和维护。当你在 when
表达式中使用主题时,它还有助于 Kotlin 检查是否涵盖了所有可能的情况。否则,如果你在 when
表达式中不使用主题,你需要提供一个 else 分支。
条件表达式实践
练习 1
创建一个简单的游戏,如果你掷两个骰子得到相同的数字,你就赢了。如果骰子匹配,使用 if
打印 You win :)
,否则打印 You lose :(
。
TIP
在本练习中,你将导入一个包,以便使用 Random.nextInt()
函数来获取一个随机的 Int
。有关导入包的更多信息,请参阅包和导入。
提示
使用相等运算符 (==
) 来比较骰子结果。
|---|---|
import kotlin.random.Random
fun main() {
val firstResult = Random.nextInt(6)
val secondResult = Random.nextInt(6)
// Write your code here
}
|---|---|
import kotlin.random.Random
fun main() {
val firstResult = Random.nextInt(6)
val secondResult = Random.nextInt(6)
if (firstResult == secondResult)
println("You win :)")
else
println("You lose :(")
}
练习 2
使用 when
表达式,更新以下程序,使其在输入游戏机按钮名称时打印相应的操作。
按钮 | 操作 |
---|---|
A | 是 |
B | 否 |
X | 菜单 |
Y | 无 |
其他 | 没有此按钮 |
|---|---|
fun main() {
val button = "A"
println(
// Write your code here
)
}
|---|---|
fun main() {
val button = "A"
println(
when (button) {
"A" -> "Yes"
"B" -> "No"
"X" -> "Menu"
"Y" -> "Nothing"
else -> "There is no such button"
}
)
}
区间
在讨论循环之前,了解如何构造供循环迭代的区间是很有用的。
在 Kotlin 中创建区间最常见的方式是使用 ..
运算符。例如,1..4
等效于 1, 2, 3, 4
。
要声明不包含结束值的区间,请使用 ..<
运算符。例如,1..<4
等效于 1, 2, 3
。
要声明倒序区间,请使用 downTo
。例如,4 downTo 1
等效于 4, 3, 2, 1
。
要声明以非 1 步长递增的区间,请使用 step
和你想要的递增值。例如,1..5 step 2
等效于 1, 3, 5
。
你也可以对 Char
区间执行相同操作:
'a'..'d'
等效于'a', 'b', 'c', 'd'
'z' downTo 's' step 2
等效于'z', 'x', 'v', 't'
循环
编程中最常见的两种循环结构是 for
和 while
。使用 for
来迭代一系列值并执行操作。使用 while
来持续执行一个操作直到满足特定条件。
for
利用你新学到的区间知识,你可以创建一个 for
循环,该循环迭代数字 1 到 5 并每次打印该数字。
将迭代器和区间放在括号 ()
内,并带上关键字 in
。将你要完成的操作放在大括号 {}
内:
fun main() {
for (number in 1..5) {
// number 是迭代器,1..5 是区间
print(number)
}
// 12345
}
集合也可以通过循环进行迭代:
fun main() {
val cakes = listOf("carrot", "cheese", "chocolate")
for (cake in cakes) {
println("Yummy, it's a $cake cake!")
}
// Yummy, it's a carrot cake!
// Yummy, it's a cheese cake!
// Yummy, it's a chocolate cake!
}
while
while
可以通过两种方式使用:
- 在条件表达式为真时执行代码块。 (
while
) - 先执行代码块,然后检查条件表达式。 (
do-while
)
在第一种用法 (while
) 中:
- 将
while
循环继续执行的条件表达式声明在括号()
内。 - 将你要完成的操作放在大括号
{}
内。
TIP
以下示例使用递增运算符 ++
来递增 cakesEaten
变量的值。
fun main() {
var cakesEaten = 0
while (cakesEaten < 3) {
println("Eat a cake")
cakesEaten++
}
// Eat a cake
// Eat a cake
// Eat a cake
}
在第二种用法 (do-while
) 中:
- 将
while
循环继续执行的条件表达式声明在括号()
内。 - 使用关键字
do
在大括号{}
内定义你要完成的操作。
fun main() {
var cakesEaten = 0
var cakesBaked = 0
while (cakesEaten < 3) {
println("Eat a cake")
cakesEaten++
}
do {
println("Bake a cake")
cakesBaked++
} while (cakesBaked < cakesEaten)
// Eat a cake
// Eat a cake
// Eat a cake
// Bake a cake
// Bake a cake
// Bake a cake
}
有关条件表达式和循环的更多信息和示例,请参阅条件和循环。
现在你已经了解了 Kotlin 控制流的基础知识,是时候学习如何编写自己的函数了。
循环实践
练习 1
你有一个程序,用于计算披萨片数,直到有 8 片的完整披萨。以两种方式重构此程序:
- 使用
while
循环。 - 使用
do-while
循环。
|---|---|
fun main() {
var pizzaSlices = 0
// Start refactoring here
pizzaSlices++
println("There's only $pizzaSlices slice/s of pizza :(")
pizzaSlices++
println("There's only $pizzaSlices slice/s of pizza :(")
pizzaSlices++
println("There's only $pizzaSlices slice/s of pizza :(")
pizzaSlices++
println("There's only $pizzaSlices slice/s of pizza :(")
pizzaSlices++
println("There's only $pizzaSlices slice/s of pizza :(")
pizzaSlices++
println("There's only $pizzaSlices slice/s of pizza :(")
pizzaSlices++
println("There's only $pizzaSlices slice/s of pizza :(")
pizzaSlices++
// End refactoring here
println("There are $pizzaSlices slices of pizza. Hooray! We have a whole pizza! :D")
}
|---|---|
fun main() {
var pizzaSlices = 0
while ( pizzaSlices < 7 ) {
pizzaSlices++
println("There's only $pizzaSlices slice/s of pizza :(")
}
pizzaSlices++
println("There are $pizzaSlices slices of pizza. Hooray! We have a whole pizza! :D")
}
|---|---|
fun main() {
var pizzaSlices = 0
pizzaSlices++
do {
println("There's only $pizzaSlices slice/s of pizza :(")
pizzaSlices++
} while ( pizzaSlices < 8 )
println("There are $pizzaSlices slices of pizza. Hooray! We have a whole pizza! :D")
}
练习 2
编写一个程序来模拟 Fizz buzz 游戏。你的任务是递增打印从 1 到 100 的数字,将任何能被三整除的数字替换为单词 "fizz",将任何能被五整除的数字替换为单词 "buzz"。任何同时能被 3 和 5 整除的数字必须替换为单词 "fizzbuzz"。
提示 1
使用 for
循环计数并使用 when
表达式来决定每一步打印什么。
提示 2
使用模运算符 (%
) 返回数字相除的余数。使用相等运算符 (==
) 来检查余数是否为零。
|---|---|
fun main() {
// Write your code here
}
|---|---|
fun main() {
for (number in 1..100) {
println(
when {
number % 15 == 0 -> "fizzbuzz"
number % 3 == 0 -> "fizz"
number % 5 == 0 -> "buzz"
else -> "$number"
}
)
}
}
练习 3
你有一个单词列表。使用 for
和 if
只打印以字母 l
开头的单词。
提示
对 String
类型使用 .startsWith()
函数。
|---|---|
fun main() {
val words = listOf("dinosaur", "limousine", "magazine", "language")
// Write your code here
}
|---|---|
fun main() {
val words = listOf("dinosaur", "limousine", "magazine", "language")
for (w in words) {
if (w.startsWith("l"))
println(w)
}
}