Enums
Что такое enum
- enum class — специальный класс для набора фиксированных констант.
- Каждая константа — отдельный экземпляр класса enum.
Объявление простого enum
enum class Direction {
NORTH, EAST, SOUTH, WEST
}
Доступ к значениям
val d: Direction = Direction.NORTH
val name = d.name // "NORTH"
val ordinal = d.ordinal // 0 (порядок объявления)
Перечисление всех значений и поиск по имени
val all = Direction.values() // Array<Direction>
val fromName = Direction.valueOf("SOUTH") // Direction.SOUTH (или бросит IllegalArgumentException)
Конструкторы и свойства
- У констант enum можно задавать параметры и хранить свойства.
enum class Planet(val mass: Double, val radius: Double) {
MERCURY(3.3011e23, 2.4397e6),
VENUS(4.8675e24, 6.0518e6),
EARTH(5.97237e24, 6.371e6);
// вспомогательный метод
fun surfaceGravity(): Double {
val G = 6.67430e-11
return G * mass / (radius * radius)
}
}
Абстрактные методы и их реализация в константах
enum class Operation {
PLUS {
override fun apply(a: Int, b: Int) = a + b
},
MINUS {
override fun apply(a: Int, b: Int) = a - b
};
abstract fun apply(a: Int, b: Int): Int
}
Реализация интерфейса
interface Printable { fun print() }
enum class Status : Printable {
STARTED { override fun print() = println("started") },
STOPPED { override fun print() = println("stopped") }
}
companion object и фабричные методы
enum class Color(val hex: String) {
RED("#FF0000"), GREEN("#00FF00"), BLUE("#0000FF");
companion object {
fun fromHex(hex: String): Color? = values().find { it.hex.equals(hex, true) }
}
}
Использование в when
- when с enum часто не требует else, если охватываются все значения (компилятор проверяет exhaustiveness).
fun action(dir: Direction) = when (dir) {
Direction.NORTH -> "up"
Direction.SOUTH -> "down"
Direction.EAST -> "right"
Direction.WEST -> "left"
}
Полезные советы
- ordinal — полезен, но не используйте его как постоянный идентификатор (порядок может измениться).
- Для безопасного преобразования из строки — лучше написать собственный метод (companion) или использовать runCatching / kotlin.Result.
- Enum оптимальны, когда набор значений невелик и фиксирован.
- Если нужен расширяемый набор типов с сопоставлением по значению — рассмотрите sealed class.
Короткая шпаргалка команд и методов
- enum class X { A, B } — объявление
- X.values() — массив всех значений
- X.valueOf("A") — получить по имени (бросает исключение)
- x.name, x.ordinal — имя и индекс
- Передача параметров — enum class X(val p: T) { A(v), B(w) }
- Могут содержать методы, companion object, реализовывать интерфейсы, иметь абстрактные методы.