
在编程中,我们常常会遇到一些有限且固定的常量集合,比如:
- 星期:周一到周日;
- 性别:男、女;
- 网络请求状态:成功、失败、加载中。
如果用普通的常量(const val)或整数来表示这些值,既不安全,也不易维护。例如:
const val STATUS_SUCCESS = 0
const val STATUS_FAIL = 1
问题:可读性差(0 和 1 的语义不直观);无类型检查(容易误用其他 Int 值);维护麻烦(新增状态要改多处代码)。
枚举类:定义了一组固定常量,每个常量都是枚举类的唯一实例。枚举类天生具备类型安全、可读性强、可扩展性好等优点。
基本使用
enum class Direction { // final 的
NORTH, SOUTH, WEST, EAST // 一般全大写
}
每个枚举常量(如 Direction.NORTH)都是 Direction 的一个实例。
fun main() {
val dir: Direction = Direction.NORTH
println(dir) // 输出:NORTH
println(dir.name) // 输出:NORTH
println(dir.ordinal) // 输出:0(下标,从 0 开始)
}
遍历所有枚举常量
for (d in Direction.entries) {
println(d)
}
枚举类也可以具有成员
枚举类不仅仅是常量集合,它还可以像普通类一样:
- 定义属性
- 定义方法
- 自定义构造函数
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF); // 需要 ;
fun toHex(): String = "#%06X".format(rgb)
}
fun main() {
println(Color.RED.rgb) // 16711680
println(Color.RED.toHex()) // #FF0000
}
枚举常量可以携带构造参数;末尾要用 ; 号分隔常量和成员定义;
在 when 表达式中使用枚举类
when 是枚举最常用的配合工具。Kotlin 编译器会检查 when 是否覆盖所有枚举项。如果你漏写一个分支,编译错误(除非加 else)。
fun getDirectionDescription(direction: Direction): String = when (direction) {
Direction.NORTH -> "向北"
Direction.SOUTH -> "向南"
Direction.EAST -> "向东"
Direction.WEST -> "向西"
}
枚举类中的抽象函数
每个枚举常量都是该枚举类的一个对象,因此可以为每个常量实现不同的行为。每个枚举常量都必须实现该函数。
enum class Operation {
ADD {
override fun apply(x: Int, y: Int) = x + y
},
SUBTRACT {
override fun apply(x: Int, y: Int) = x - y
},
MULTIPLY {
override fun apply(x: Int, y: Int) = x * y
},
DIVIDE {
override fun apply(x: Int, y: Int) = x / y
};
abstract fun apply(x: Int, y: Int): Int
}
fun main() {
println(Operation.ADD.apply(2, 3)) // 5
}
枚举类实现接口
枚举类可以实现接口,每个常量也可以有独立实现。
interface Printable {
fun print()
}
enum class Status : Printable {
SUCCESS {
override fun print() = println("操作成功")
},
ERROR {
override fun print() = println("操作失败")
},
LOADING {
override fun print() = println("正在加载")
}
}
fun main() {
Status.SUCCESS.print() // 输出:操作成功
}
常用枚举类相关函数
| 函数 | 作用 |
|---|---|
entries | 返回所有枚举常量列表,EnumEntries<T> |
valueOf(name: String) | 根据枚举常量名称返回对应枚举值(找不到会抛异常),T |
name | 获取枚举常量名称,String |
ordinal | 获取枚举常量序号(从 0 开始),Int |
enumValues<T>() | 返回枚举类的所有常量数组,泛型安全版,替代values(),Array<T> |
enumValueOf<T>(name) | 泛型安全版 valueOf,T |
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF)
}
// EnumEntries<T>实现了List<T>接口,可当作List<T>
val list: EnumEntries<Color> = Color.entries
println(list) // 输出:[RED, GREEN, BLUE]
println(list[1]) // 输出:GREEN
println(list.size) // 输出:3
val color: Color = Color.valueOf("RED")
println(color) // RED
val color: Color = Color.GREEN
println(color.name) // GREEN
println(Color.RED.ordinal) // 0
println(Color.GREEN.ordinal) // 1
println(Color.BLUE.ordinal) // 2
val c: Color = enumValueOf("BLUE")
val c = enumValueOf("BLUE") // 编译错误
val c = enumValueOf<Color>("BLUE")
val c: Color = enumValueOf<Color>("BLUE")
println(c) // BLUE
val all: Array<Color> = enumValues<Color>()
println(all.joinToString()) // RED, GREEN, BLUE
478

被折叠的 条评论
为什么被折叠?



