Skip to content

控制流

与其他编程语言一样,Kotlin 能够根据一段代码的求值结果是否为真来做出决策。这类代码称为条件表达式。Kotlin 还能够创建和遍历循环。

条件表达式

Kotlin 提供了 ifwhen 来检查条件表达式。

NOTE

如果你必须在 ifwhen 之间做出选择,我们推荐使用 when,因为它:

  • 使你的代码更易读。

  • 使其更容易添加另一个分支。

  • 减少代码中的错误。

if

要使用 if,请将条件表达式放在括号 () 内,并将当结果为真时要执行的操作放在大括号 {} 内:

kotlin
fun main() {
    val d: Int
    val check = true

    if (check) {
        d = 1
    } else {
        d = 2
    }

    println(d)
    // 1
}

Kotlin 中没有三元运算符 condition ? then : else。相反,if 可以用作表达式。如果每个操作只有一行代码,则大括号 {} 是可选的:

kotlin
fun main() { 
    val a = 1
    val b = 2

    println(if (a > b) a else b) // Returns a value: 2
}

when

当你的条件表达式有多个分支时,使用 when

要使用 when

  • 将你要评估的值放在括号 () 内。
  • 将分支放在大括号 {} 内。
  • 在每个分支中使用 -> 来分隔每个检查和当检查成功时要执行的操作。

when 既可以用作语句,也可以用作表达式。语句不返回任何内容,而是执行操作。

以下是使用 when 作为语句的示例:

kotlin
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() 函数一起使用:

kotlin
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 表达式来检查一系列布尔表达式:

kotlin
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 作为主题:

kotlin
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。有关导入包的更多信息,请参阅包和导入

提示

使用相等运算符 (==) 来比较骰子结果。

|---|---|

kotlin
import kotlin.random.Random

fun main() {
    val firstResult = Random.nextInt(6)
    val secondResult = Random.nextInt(6)
    // Write your code here
}

|---|---|

kotlin
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
其他没有此按钮

|---|---|

kotlin
fun main() {
    val button = "A"

    println(
        // Write your code here
    )
}

|---|---|

kotlin
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'

循环

编程中最常见的两种循环结构是 forwhile。使用 for 来迭代一系列值并执行操作。使用 while 来持续执行一个操作直到满足特定条件。

for

利用你新学到的区间知识,你可以创建一个 for 循环,该循环迭代数字 1 到 5 并每次打印该数字。

将迭代器和区间放在括号 () 内,并带上关键字 in。将你要完成的操作放在大括号 {} 内:

kotlin
fun main() {
    for (number in 1..5) { 
        // number 是迭代器,1..5 是区间
        print(number)
    }
    // 12345
}

集合也可以通过循环进行迭代:

kotlin
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 变量的值。

kotlin
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 在大括号 {} 内定义你要完成的操作。
kotlin
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 循环。

|---|---|

kotlin
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")
}

|---|---|

kotlin
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")
}

|---|---|

kotlin
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

使用模运算符 (%) 返回数字相除的余数。使用相等运算符 (==) 来检查余数是否为零。

|---|---|

kotlin
fun main() {
    // Write your code here
}

|---|---|

kotlin
fun main() {
    for (number in 1..100) {
        println(
            when {
                number % 15 == 0 -> "fizzbuzz"
                number % 3 == 0 -> "fizz"
                number % 5 == 0 -> "buzz"
                else -> "$number"
            }
        )
    }
}

练习 3

你有一个单词列表。使用 forif 只打印以字母 l 开头的单词。

提示

String 类型使用 .startsWith() 函数。

|---|---|

kotlin
fun main() {
    val words = listOf("dinosaur", "limousine", "magazine", "language")
    // Write your code here
}

|---|---|

kotlin
fun main() {
    val words = listOf("dinosaur", "limousine", "magazine", "language")
    for (w in words) {
        if (w.startsWith("l"))
            println(w)
    }
}

下一步

函数