枚举
枚举是一组名称的集合。
Kotlin中的enum class
是管理这些名称的便捷方式:
// Enumerations/Level.kt
package enumerations
import atomictest.eq
enum class Level {
Overflow, High, Medium, Low, Empty
}
fun main() {
Level.Medium eq "Medium"
}
创建一个枚举会生成enum
名称的toString()
方法。
在main()
中,您必须对枚举名称的每个引用进行限定,就像Level.Medium
一样。您可以使用import
将枚举中的所有名称引入到当前的命名空间(命名空间可以防止名称之间的冲突):
// Enumerations/EnumImport.kt
import atomictest.eq
import enumerations.Level.* // [1]
fun main() {
Overflow eq "Overflow"
High eq "High"
}
- [1]
*
导入了Level
枚举内的所有名称,但不导入Level
这个名称本身。
您可以将枚举值导入到定义枚举类的同一个文件中:
// Enumerations/RecursiveEnumImport.kt
package enumerations
import atomictest.eq
import enumerations.Size.* // [1]
enum class Size {
Tiny, Small, Medium, Large, Huge, Gigantic
}
fun main() {
Gigantic eq "Gigantic" // [2]
Size.values().toList() eq // [3]
listOf(Tiny, Small, Medium,
Large, Huge, Gigantic)
Tiny.ordinal eq 0 // [4]
Huge.ordinal eq 4
}
- [1] 我们在
Size
定义出现之前就导入了Size
的值。 - [2] 在
import
之后,我们不再需要限定访问枚举名称。 - [3] 您可以使用
values()
遍历枚举名称。values()
返回一个数组,因此我们调用toList()
将其转换为列表。 - [4]
enum
的第一个声明的常量具有ordinal
值为零。每个后续的常量都会获得下一个整数值。
您可以使用when
表达式对不同的枚举条目执行不同的操作。这里,我们导入了Level
的名称以及其所有条目:
// Enumerations/CheckingOptions.kt
package checkingoptions
import atomictest.*
import enumerations.Level
import enumerations.Level.*
fun checkLevel(level: Level) {
when (level) {
Overflow -> trace(">>> Overflow!")
Empty -> trace("Alert: Empty")
else -> trace("Level $level OK")
}
}
fun main() {
checkLevel(Empty)
checkLevel(Low)
checkLevel(Overflow)
trace eq """
Alert: Empty
Level Low OK
>>> Overflow!
"""
}
checkLevel()
仅针对两个常量执行特定的操作,而对于其他所有选项则表现正常(else
情况)。
枚举是一种特殊类型的类,它有固定数量的实例,这些实例都列在类体内。除此之外,enum
类的行为与常规类相同,因此您可以定义成员属性和函数。如果包含额外的元素,则必须在最后一个枚举值后添加一个分号:
// Enumerations/Direction.kt
package enumerations
import atomictest.eq
import enumerations.Direction.*
enum class Direction(val notation: String) {
North("N"), South("S"),
East("E"), West("W"); // 需要分号
val opposite: Direction
get() = when (this) {
North -> South
South -> North
West -> East
East -> West
}
}
fun main() {
North.notation eq "N"
North.opposite eq South
West.opposite.opposite eq West
North.opposite.notation eq "S"
}
Direction
类包含一个notation
属性,每个实例都持有不同的值。您可以在括号中传递notation
构造函数参数的值(例如North("N")
),就像构造常规类的实例一样。
opposite
属性的getter在访问时动态计算结果。
请注意,此示例中的when
不需要else
分支,因为所有可能的enum
条目都已覆盖。
枚举可以使代码更具可读性,这总是值得提倡的。
Exercises and solutions can be found at www.AtomicKotlin.com.