在 Kotlin 中添加条件行为

1. 准备工作

在此 Kotlin Codelab 中,您将创建名为 Lucky Dice Roll 的一款骰子游戏,试着掷出一个幸运数字。此游戏程序将设置一个幸运数字,并掷出骰子。然后,程序会对照幸运数字检查掷出的数字,并在输出端显示适当的消息。为此,您将学习如何在 Kotlin 程序中比较数值并做出不同的决策。

为帮助您专注于编程概念,而无需担心应用的界面,您将使用基于浏览器的 Kotlin 编程工具,并将结果输出到控制台。

前提条件

学习内容

  • 如何使用 ifelse 语句。
  • 如何使用大于 (>)、小于 (<) 以及等于 (==) 等运算符来比较数值。
  • 如何使用 when 语句来根据给定值选择一个选项。
  • Boolean 数据类型是什么,以及如何使用其 truefalse 值来做出决策。

构建内容

  • 一款基于 Kotlin 的骰子游戏 Lucky Dice Roll,您可以在其中指定一个幸运数字。如果玩家掷出这个幸运数字,玩家就会获胜。

所需工具

  • 一台已连接互联网的计算机。

2. 在代码内做出决策

您的 Lucky Dice Roller 程序需要确定用户是否掷出了幸运数字,如果用户掷出了幸运数字,则会收到祝贺消息,如果没有,则会收到重试消息。

作为应用开发者,您需要决定应用的行为方式,并为用户创建不同的结果。

如果构建的是购物应用,您可能会根据用户选择的送货选项显示不同的屏幕。对于益智游戏,您需要根据玩家的答案是否正确显示不同的屏幕。根据具体应用,您可能需要在代码中考虑多种可能的结果。

在您的 Lucky Dice Roller 程序中,应用应处理不同的情况,例如:

  • if 用户掷出幸运数字,就显示祝贺消息!
  • else if 用户未掷出幸运数字,就显示重试消息。

如需将此逻辑添加到代码中,请使用特殊的 Kotlin 关键字,例如 ifelsewhen

我们来看一些示例。

使用 if 语句设置满足的条件

  1. 检查下方的代码。您能否猜出输出内容是什么?
fun main() {
   val num = 5
   if (num > 4) {
       println("The variable is greater than 4")
   }
}
  1. 复制这些代码并将其粘贴到 Kotlin 程序编辑器中,然后运行该程序以观察输出结果。
The variable is greater than 4

该程序的决策过程如下:

  1. 创建变量 num 并将其设置为 5.
  2. 如果 num 大于 4,就输出 "The variable is greater than 4"
  3. 在所有其他情况下,不执行任何操作。

在上述示例中,num 设置为 5。if 语句会比较变量是否大于 4。由于比较结果为 true,系统接下来会执行大括号中的指令并输出消息。

请注意 if 语句的一般格式:

  • if 关键字开头。
  • 后跟一对圆括号 ()。括号内包含条件。该条件是结果可以为 truefalse 的任何条件。例如,一个数字是否大于另一个数字。
  • 再后跟一对大括号 {}。在大括号内放置条件结果为 true 时要执行的代码。
if (condition-is-true) {
    execute-this-code
}

使用 if 语句设置未满足的条件

  1. num 的值更改为 3,如下所示。运行这段代码后,会出现什么情况?
fun main() {
    val num = 3
    if (num > 4) {
        println("The variable is greater than 4")
    }
}
  1. 复制这些代码并将其粘贴到 Kotlin 程序编辑器中,然后运行该程序以观察输出结果是否为空。

num 设置为 3,不会输出任何内容,因为 num 的值小于 4。num 大于 4 的条件结果是 false,大括号内的代码不会执行,因而不会输出任何内容。

使用 else 为未满足的条件创建替代条件

如果未满足条件,您可以为用户提供替代条件,而不是什么也不做。就像使用常规语言一样,您可以使用 else 语句来实现这一点。

  1. 添加一个 else 语句,以在 num 不大于 4 的情况下输出消息,如下所示。运行这段代码后,会出现什么情况?
fun main() {
    val num = 3
    if (num > 4) {
        println("The variable is greater than 4")
    } else {
        println("The variable is less than 4")
    }
}
  1. 复制这些代码并将其粘贴到 Kotlin 程序编辑器中,然后运行该程序以观察输出结果。
The variable is less than 4
  1. 请注意,当 num 的值为 3 时,程序会输出与 else 语句关联的消息“The variable is less than 4”,因为 num 不大于 4。
  2. num 更改为 5,然后重新运行该程序。现在,num 大于 4,程序会输出“The variable is greater than 4”。
  3. num 更改为 4,然后运行该程序。现在,4 不大于 4,程序会输出“The variable is less than 4”。

虽然“The variable is less than 4”是您在代码中设置的条件的正确输出,但输出的语句不准确,因为 4 不小于 4。您可以添加另一个条件,用于检查第三种可能性,即 num 正好为 4 的情况,在满足该条件时输出正确的语句。

使用 else + if 组合添加替代条件

您可以设置多个条件。例如,您可以使用如下条件涵盖 num 的所有可能性:

  • if num 大于 4,则输出 "The variable is greater than 4"
  • else if num 为 4,就输出 "The variable is equal to 4"
  • else,就输出 "The variable is less than 4"

这些条件在 if-else 语句中被称为不同的情况。上面列出了 3 种情况。

更新后的代码如下所示:

fun main() {
    val num = 4
    if (num > 4) {
        println("The variable is greater than 4")
    } else if (num == 4) {
        println("The variable is equal to 4")
    } else {
        println("The variable is less than 4")
    }
}

请注意以下变化:

  • num 的值现在设置为 4,以便您可以测试新条件。
  • 在原始的 ifelse 语句之间是新的 else if 语句,适用于 num 正好为 4 的情况。
  1. 复制以上代码并将其粘贴到 Kotlin 程序编辑器中,然后运行该程序以观察输出结果。
The variable is equal to 4
  1. 尝试更改 num 的值,看看会对输出结果产生什么影响。将 num 更改为 2 和 6,以便可以看到每个条件变为 true

控制流

可以看出,根据上面的 if-else 语句,代码将按照条件的控制执行或向下继续运行。您使用这些条件来引导程序执行的过程称为程序的“控制流”。

  • 假设掷骰子的 num 是 3。程序会检查第一个条件 (num > 4)。该结果为 false,因此程序会检查下一个条件 (num == 4),其结果同样为 false。然后,程序会执行 else 语句的代码,这是最后一个选项。
  • 如果掷骰子的 num 为 6,那么第一个条件 (num > 4) 的结果为 true。程序会输出“The variable is greater than 4”消息。由于该条件结果为 true,因此无需检查其余条件,程序运行到 if-else 语句便已结束。
  • 使用 else + if 组合可以添加替代条件。

3. 创建 Lucky Dice Roll 游戏

在本部分中,您将使用在上一任务中学到的知识,更新 Dice Roller 程序以检查是否掷出预设的幸运数字。如果掷出预设的幸运数字,您就获胜了!

设置起始代码

您将使用与之前 Kotlin Dice Roller 程序的解决方案代码相似的代码来开始构建 Lucky Dice Roller。您可以修改之前代码中的 main() 函数以进行匹配,也可以复制并粘贴以下代码来开始构建。

fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    println("Your ${myFirstDice.numSides} sided dice rolled ${rollResult}!")
}

class Dice (val numSides: Int) {

    fun roll(): Int {
        return (1..numSides).random()
    }
}

查看是否已掷出幸运数字

请先创建幸运数字,然后将掷出的数字与该数字进行比较。

  1. main() 中,删除 println() 语句。
  2. main() 中,添加一个名为 luckyNumberval,并将其设置为 4。您的代码应如下所示。
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4
}
  1. 在下面添加一个 if 语句,在括号 () 中放置条件,用于检查 rollResult 是否等于 (==) luckyNumber。在大括号 {} 内留一些空间,以便添加更多代码。
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4
    if (rollResult == luckyNumber) {

    }
}
  1. 在大括号 {} 内,添加一个 println 语句以输出 "You win!"
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    if (rollResult == luckyNumber) {
        println("You win!")
    }
}
  1. 运行程序。您可能需要反复运行几次才能得到幸运数字并看到输出中显示获胜消息!
You win!

在尚未掷出幸运数字时做出响应

在用户没有获胜的情况下,如果程序不提供任何反馈,用户可能会怀疑程序是否已发生故障。最好的做法是始终在用户执行操作时提供响应。对于 Lucky Dice Roller 程序,您可以使用 else 语句让用户知道自己没有获胜。

  1. 添加 else 语句以输出 "You didn't win, try again!"
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    if (rollResult == luckyNumber) {
        println("You win!")
    } else {
        println("You didn't win, try again!")
    }
}
  1. 运行程序,无论结果如何,用户都会收到消息通知。

这种情况下,用户会知道自己是否获胜,但不知道其中的原因。请务必向用户提供信息,以便他们了解操作的结果!假设您的程序是贷款应用。“由于您的信用评级不佳,您未获得批准”就比“抱歉,您无法获得贷款,请重试”信息更全面。在 Lucky Dice Roller 中,对于用户未获胜的情况,您可以针对每一次掷骰提供不同的参考消息。要实现此目的,请使用多个 else if 语句。

  1. 添加 else if 语句以针对每次掷骰输出不同的消息。如果需要,请参考您在上一任务中学到的格式。
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    if (rollResult == luckyNumber) {
        println("You win!")
    } else if (rollResult == 1) {
        println("So sorry! You rolled a 1. Try again!")
    } else if (rollResult == 2) {
        println("Sadly, you rolled a 2. Try again!")
    } else if (rollResult == 3) {
        println("Unfortunately, you rolled a 3. Try again!")
    } else if (rollResult == 5) {
        println("Don't cry! You rolled a 5. Try again!")
    } else {
        println("Apologies! You rolled a 6. Try again!")
    }
}

在以上代码中,您应

  • 检查 rollResult 是否为 luckyNumber
  • 如果 rollResultluckyNumber,就输出获胜消息。
  • 否则,检查 rollResult 是否为 1,如果是,就输出重试消息。
  • 否则,检查 rollResult 是否为 2,如果是,就输出另一条不同的重试消息。
  • 否则,继续进行检查,直到数字 5。
  • 如果数字并非 1 到 5 之间的任何数字,就只剩唯一一个选项 6,因此无需使用 else if 进行另一次测试,只需使用最后的 else 语句即可捕获该最后一个选项。

由于有多个 else if 的情况很常见,因此 Kotlin 提供了一种更简单的编写方法。

4. 使用 when 语句

针对许多不同结果(或情况)进行测试在编程中很常见。有时,可能的结果非常多。例如,如果是掷 12 面的骰子,获得成功结果与最后的 else 之间会有 11 个 else if 语句。为了使此类语句更易于读写,从而帮助避免错误,Kotlin 提供了 when 语句。

您将更改程序,以使用 when 语句。when 语句以关键字 when 开头,后跟括号 ()。括号内放置要测试的值。后跟大括号 {},这样可以针对不同的条件执行代码。

  1. 在您的程序内,在 main() 中,选择从第一个 if 语句到括住最后一个 else 语句的大括号 } 之间的代码并将其删除。
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4
}
  1. main() 中的 luckyNumber 声明下方,创建一个 when 语句。由于 when 需要针对掷出的结果进行测试,因此请将 rollResult 放置在括号 () 内。添加大括号 {} 并留出一些额外的空间,如下所示。
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    when (rollResult) {

    }
}

与之前一样,首先测试 rollResult 是否与 luckyNumber 相同。

  1. when 语句的大括号 {} 内,添加一个针对 luckyNumber 测试 rollResult 的语句,如果二者相同,就输出获胜消息。该语句如下所示:
luckyNumber -> println("You win!")

这意味着:

  • 您首先放入要与 rollResult 比较的值。即,luckyNumber
  • 后跟箭头 (->)。
  • 然后添加存在匹配项时要执行的操作。

这可以理解为,“如果 rollResultluckyNumber,就输出 "You win!" 消息。”

您的 main() 代码如下所示。

fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    when (rollResult) {
        luckyNumber -> println("You win!")
    }
}
  1. 使用相同格式为可能的掷骰结果 1 至 6(4 除外)添加代码行和消息,如下所示。完成后的 main() 函数应如下所示。
fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    when (rollResult) {
        luckyNumber -> println("You won!")
        1 -> println("So sorry! You rolled a 1. Try again!")
        2 -> println("Sadly, you rolled a 2. Try again!")
        3 -> println("Unfortunately, you rolled a 3. Try again!")
        5 -> println("Don't cry! You rolled a 5. Try again!")
        6 -> println("Apologies! You rolled a 6. Try again!")
    }
}
  1. 运行程序。输出内容没有差异,但代码更紧凑,也更易读。

恭喜!您已掌握了根据条件输出消息的两种方法。这是非常强大的方法,可用来编写各种有趣的程序!

5. 解决方案代码

fun main() {
    val myFirstDice = Dice(6)
    val rollResult = myFirstDice.roll()
    val luckyNumber = 4

    when (rollResult) {
        luckyNumber -> println("You won!")
        1 -> println("So sorry! You rolled a 1. Try again!")
        2 -> println("Sadly, you rolled a 2. Try again!")
        3 -> println("Unfortunately, you rolled a 3. Try again!")
        5 -> println("Don't cry! You rolled a 5. Try again!")
        6 -> println("Apologies! You rolled a 6. Try again!")
   }
}

class Dice(val numSides: Int) {
    fun roll(): Int {
        return (1..numSides).random()
    }
}

6. 总结

  • 使用 if 语句设置用于执行某些指令的条件。例如,如果用户掷出幸运数字,就输出获胜消息。
  • Boolean 数据类型的值为 truefalse,可用于做出决策。
  • 使用大于 (>)、小于 (<) 和等于 (==) 等运算符可比较数值。
  • 使用 else if 语句链可设置多个条件。例如,针对每种可能的掷骰结果输出不同的消息。
  • 在条件链末尾使用 else 语句来捕获您未明确涵盖的任何情况。如果您涵盖掷 6 面骰子的情况,else 语句将捕获使用 8 面骰子时的数字 7 和 8。
  • 使用 when 语句作为基于比较数值的一种紧凑的代码执行方法。

if-else 的常规形式

if (condition-is-true) {
    execute-this-code
} else if (condition-is-true) {
    execute-this-code
} else {
    execute-this-code
}

when 语句

when (variable) {
    matches-value -> execute-this-code
    matches-value -> execute-this-code
    ...
}

7. 了解更多内容

8. 自行练习

进行以下练习

  1. myFirstDice 更改为包含 8 个面并运行代码。会出现什么情况?

提示:当您增加面数时,when 语句不再涵盖所有情况,因此对于未涵盖的情况,系统不会输出任何内容。

  1. 修正 when 语句,以涵盖全部 8 个面。为此,您可以添加针对其他数字的情况。挑战:使用 else 语句捕获所有未明确涵盖的情况,而不是针对每个数字添加新情况。

提示:您可以添加更多情况以涵盖更多面。如果您希望针对每个可掷出的数字显示不同的消息,这是一种不错的方法。或者,您也可以使用 else 语句,针对当前代码涵盖的所有大于 6 的面输出相同的消息。

  1. myFirstDice 改为只有 4 个面。会出现什么情况?

提示:将骰子的面数更改为小于 when 语句所涵盖的范围不会产生任何明显影响,因为可能发生的所有情况都涵盖在内。