Kotlin 枚举和 when 表达式(六)
导读大纲
- 1.1 表示和处理选择: Enums和when
- 1.1.1 声明枚举类和枚举常量
- 1.1.2 使用 when 表达式处理枚举类
1.1 表示和处理选择: Enums和when
- 在本节中,我们将以在 Kotlin 中声明枚举为例,介绍 when 结构
- when可以被视为比 Java 中 switch 结构更强大、更常用的替代品
1.1.1 声明枚举类和枚举常量
- 在这里,你必须用 Kotlin 代码来实现它们,特别是颜色常量枚举
- 这是 Kotlin 比相应 Java 使用更多关键字的罕见情况
- kotlin中的
枚举类(enum class)
与 Java 中的枚举(enum)
- kotlin中的
- 这是 Kotlin 比相应 Java 使用更多关键字的罕见情况
package colors
enum class Color {
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
INDIGO,
VIOLET
}
-
在 Kotlin 中,enum 是一个所谓的软关键字
- 当它出现在 class 之前时,它就有特殊的含义
- 但你也可以在其他地方将它用作常规名称(例如函数、变量名或参数)
- 另一方面,class 是一个硬关键字,这意味着不能将它用作标识符
- 必须使用另一种拼写或措辞,如 clazz 或 aClass
- 当它出现在 class 之前时,它就有特殊的含义
-
将颜色存储在枚举中很有用,但我们可以做得更好
- 颜色值通常使用红、绿、蓝三原色来表示
- 枚举常量使用相同的构造函数和属性声明语法
- 就像你在前面看到的普通类一样
- 您可以利用这一点来扩展Color枚举
- 您可以将每个枚举常量与其 r、g 和 b 值关联起来
- 您还可以使用熟悉的语法声明属性(如 rgb)和方法(如printColor)
-
示例–带有属性值的枚举类
- <1> 声明枚举常量的属性
- <2> 在创建每个常量时指定属性值
- <3> 这里的分号是必需的
- <4> 定义枚举类的属性
- <5> 定义枚举类的方法
- 这里又是表达式体形式的函数, 符合Kotlin本土化
- 请注意,这个例子展示 Kotlin 语法中唯一需要使用分号的地方
- 如果你在枚举类中定义非枚举常量的声明(比如方法或属性)
- 分号会将枚举常量与其他声明分离
- 如果你在枚举类中定义非枚举常量的声明(比如方法或属性)
enum class Color(
val r: Int, // <1>
val g: Int,
val b: Int,
) {
RED(255, 0, 0), // <2>
ORANGE(255, 165, 0),
YELLOW(255, 255, 0),
GREEN(0, 255, 0),
BLUE(0, 0, 255),
INDIGO(75, 0, 130),
VIOLET(238, 130, 238); // <3>
val rgb = (r * 256 + g) * 256 + b // <4>
fun printColor() = println("$this is $rgb") // <5>
}
fun main() {
println(Color.BLUE.rgb)
// 255
Color.GREEN.printColor()
// GREEN is 65280
}
1.1.2 使用 when 表达式处理枚举类
-
在 Java 中,您可以使用 switch 语句
- 或者从 Java 13开始使用 switch 表达式
- 相应的 Kotlin 结构是 when 表达式
-
和 if 一样,"when"也是一个返回值的表达式
- <1> 直接返回when表达式,这就是表达式体函数的语言魅力
- 使用块体,最起码的大括号和返回语句是少不了的
- <2> 如果颜色等于枚举常量, 则返回相应的字符串
- <1> 直接返回when表达式,这就是表达式体函数的语言魅力
fun getMnemonic(color: Color) = // <1>
when (color) { // <2>
Color.RED -> "Richard"
Color.ORANGE -> "Of"
Color.YELLOW -> "York"
Color.GREEN -> "Gave"
Color.BLUE -> "Battle"
Color.INDIGO -> "In"
Color.VIOLET -> "Vain"
}
fun main() {
println(getMnemonic(Color.BLUE))
// Battle
}
- 代码会找到与传递的颜色值相对应的分支
- 请注意,您不需要为每个分支编写 break 语句
- 在 Java 中,在 switch 语句中缺少 break 语句往往会导致错误
- 如果匹配成功,则只执行相应的分支
- <1> 还可以在同一分支中合并多个值,此时需要用逗号分隔多个值
- 请注意,您不需要为每个分支编写 break 语句
fun measureColor() = Color.ORANGE
// as a stand-in for more complex measurement logic
fun getWarmthFromSensor(): String {
val color = measureColor()
return when(color) {
// <1>
Color.RED, Color.ORANGE, Color.YELLOW -> "warm (red = ${color.r})"
Color.GREEN -> "neutral (green = ${color.g})"
Color.BLUE, Color.INDIGO, Color.VIOLET -> "cold (blue = ${color.b})"
}
}
fun main() {
println(getWarmthFromSensor())
// warm (red = 255)
}
- 通过使用"Color.*"来导入所有的常量值,可以简化代码并减少重复
- 避免每次引用枚举常量时都指定 Color 枚举类名
- <1> 导入所有枚举常量,以便按名称使用它们
- <2> 按名称使用导入的枚举常量
import colors.Color.* // <1>
fun measureColor() = ORANGE
// as a stand-in for more complex measurement logic
fun getWarmthFromSensor(): String {
val color = measureColor()
return when(color) {
RED, ORANGE, YELLOW -> "warm (red = ${color.r})" // <2>
GREEN -> "neutral (green = ${color.g})"
BLUE, INDIGO, VIOLET -> "cold (blue = ${color.b})" // <2>
}
}