ZetCode

Kotlin 枚举关键字

最后修改于 2025 年 4 月 19 日

Kotlin 的枚举类提供了一种定义一组相关常量的强大方法。enum 关键字创建具有属性和方法的类型安全枚举。本教程通过实际示例深入探讨枚举类。

基本定义

Kotlin 中的 enum 关键字声明一个枚举类。枚举类将变量限制为仅具有预定义的值。它们可以具有属性、方法并实现接口,同时保持类型安全。

基本枚举声明

最简单的枚举类只包含一个常量列表。每个常量都是枚举类的实例。与使用普通常量相比,枚举提供了类型安全。

BasicEnum.kt
package com.zetcode

enum class Direction {
    NORTH, SOUTH, EAST, WEST
}

fun main() {

    val dir = Direction.NORTH
    
    when (dir) {
        Direction.NORTH -> println("Going North")
        Direction.SOUTH -> println("Going South")
        Direction.EAST -> println("Going East")
        Direction.WEST -> println("Going West")
    }
}

在这里,我们定义了一个简单的 Direction 枚举,其中包含四个常量。在 main() 中,我们将 NORTH 分配给一个变量,并使用 when 表达式来处理每种情况。编译器确保我们处理了所有可能的枚举值。

带有属性的枚举

枚举常量可以有属性。每个常量在声明时都必须为其属性提供值。属性使枚举更具表现力和实用性。

EnumWithProperties.kt
package com.zetcode

enum class Color(val rgb: Int) {
    RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF)
}

fun main() {

    val color = Color.RED
    println("RGB value of ${color.name}: ${color.rgb}")
}

这个 Color 枚举类有一个属性 rgb,用于存储十六进制颜色值。每个常量提供其特定的 rgb 值。我们在 main 函数中访问枚举名称及其属性。

带有方法的枚举

枚举类可以定义所有常量继承的方法。每个常量还可以重写这些方法以提供特定的行为。这使得枚举功能强大。

EnumWithMethods.kt
package com.zetcode

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
    };
    
    abstract fun apply(x: Int, y: Int): Int
}

fun main() {

    val op = Operation.ADD
    println("5 + 3 = ${op.apply(5, 3)}")
}

在这里,我们定义了一个 Operation 枚举,其中包含一个抽象方法 apply()。每个常量以不同的方式实现此方法。main 函数演示了使用 ADD 操作执行加法。

实现接口的枚举

枚举类可以实现接口。然后,每个常量可以提供其自己的接口方法实现。这允许使用枚举进行多态行为。

EnumImplementingInterface.kt
package com.zetcode

interface Printer {
    fun print()
}

enum class MessageType : Printer {
    INFO {
        override fun print() {
            println("Information message")
        }
    },
    WARNING {
        override fun print() {
            println("Warning message")
        }
    };
}

fun main() {

    val msg = MessageType.WARNING
    msg.print()
}

MessageType 枚举实现了 Printer 接口。每个常量提供其自己的 print() 方法实现。在 main() 中,我们调用了 WARNING 常量上的 print(),演示了多态行为。

带有自定义构造函数的枚举

枚举类可以具有构造函数,用于使用特定值初始化常量。每个常量在声明时都必须将参数传递给构造函数。这可以实现丰富的枚举定义。

EnumWithConstructor.kt
package com.zetcode

enum class Planet(val mass: Double, val radius: Double) {
    MERCURY(3.303e+23, 2.4397e6),
    VENUS(4.869e+24, 6.0518e6),
    EARTH(5.976e+24, 6.37814e6);
    
    val surfaceGravity: Double
        get() = 6.67300E-11 * mass / (radius * radius)
}

fun main() {

    val earth = Planet.EARTH
    println("Earth surface gravity: ${earth.surfaceGravity}")
}

Planet 枚举有一个构造函数,它接受质量和半径参数。每个常量都提供这些值。该枚举还有一个计算属性 surfaceGravity,它使用这些值来计算重力。

迭代枚举值

Kotlin 提供了 values 函数来获取枚举类的所有常量。这允许迭代枚举的所有可能值。

IterateEnum.kt
package com.zetcode

enum class Season {
    SPRING, SUMMER, AUTUMN, WINTER
}

fun main() {

    for (season in Season.values()) {
        println(season)
    }
}

此示例演示了如何使用 values() 函数迭代 Season 枚举的所有值。for 循环将每个季节常量打印到控制台。

将枚举与 When 表达式一起使用

枚举与 Kotlin 的 when 表达式配合得特别好。编译器可以验证是否涵盖了所有枚举情况,从而使具有枚举的 when 表达式详尽无遗。

EnumWithWhen.kt
package com.zetcode

enum class TrafficLight {
    RED, YELLOW, GREEN
}

fun getMessage(light: TrafficLight): String {
    return when (light) {
        TrafficLight.RED -> "Stop"
        TrafficLight.YELLOW -> "Caution"
        TrafficLight.GREEN -> "Go"
    }
}

fun main() {

    println(getMessage(TrafficLight.RED))
}

getMessage 函数使用 when 表达式根据 TrafficLight 枚举值返回不同的消息。编译器确保处理了所有枚举情况。main 函数演示了使用红色灯调用此函数。

枚举用法的最佳实践

来源

Kotlin 枚举类文档

本教程深入探讨了 Kotlin 的 enum 关键字,展示了从基本声明到高级用法的用法。我们探讨了属性、方法、接口和实际示例。枚举为固定的一组相关常量提供了类型安全和组织。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有多年的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我已经撰写了 1400 多篇文章和 8 本电子书。我有超过八年的编程教学经验。

列出 所有 Kotlin 教程