Классы перечисления #
Васильев Андрей Михайлович, 2024
Версии презентации
Описание классов-перечислений #
Наиболее базовый пример использования классов-перечислений — это реализация типобезопасных перечислений
enum class Direction {
NORTH, SOUTH, WEST, EAST
;
}- Каждая константа перечисления является объектом
- При объявлении константы разделяются запятыми
- Перечисление констант завершается точкой с запятой
- После точки с запятой идёт описание функций-членов и объектов-компаньонов
Данные констант #
Так как константы являются экземплярами enum-класса, они могут быть инициализированы
enum class Color(val rgb: Int, val description: String) {
RED(0xFF0000, "Красный"),
GREEN(0x00FF00, "Зелёный"),
BLUE(0x0000FF, "Синий"),
;
}К полям объекта можно обращаться как к обычным полям
val color = Color.GREEN
println(color.description)Стандартные данные констант #
Каждая enum-константа имеет поля, в которых содержатся её имя и порядковый номер в объявлении enum-класса
Вы не можете переопределить данные поля
val name: String
val ordinal: IntТакже enum-константы реализуют интерфейс Comparable. Порядок сортировки
соответствует порядку объявления
println(RGB.RED.name) // prints RED
println(RGB.RED.ordinal) // prints 0Работа с enum-константами #
Enum-классы в Kotlin имеют синтетические методы для вывода списка объявленных enum-констант и для получения enum-константы по её имени
enum class RGB { RED, GREEN, BLUE }
RGB.valueOf(value: String): RGB
RGB.entries: EnumEntries<RGB>Метод valueOf() выбрасывает исключение IllegalArgumentException, если
указанное имя не соответствует ни одной enum-константе, объявленной в классе
fun main() {
for (color in RGB.entries) println(color.toString())
println("The first color is: ${RGB.valueOf("RED")}")
}В Kotlin до 1.8 вместо entries предоставлялся метод values(), который
возвращал новый массив из констант
Обобщённый доступ к константам #
К константам в enum-классе можно получить доступ универсальным способом,
используя функции enumEntries
inline fun <reified T : Enum<T>> printAllValues() {
print(enumEntries<T>().joinToString { it.name })
}
printAllValues<RGB>() // выведет RED, GREEN, BLUEВ Kotlin до 1.8 вместо enumEntries<T>() предоставлялся метод
enumValues<T>(), который также возвращает новый массив из констант
Условное выражение when #
when определяет условное выражение с несколькими «ветвями». Оно похоже на
оператор switch, присутствующий в C-подобных языках.
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // обратите внимание на блок
print("x не равен ни 1, ни 2")
}
}when последовательно сравнивает свой аргумент со всеми указанными значениями,
пока не выполнится какое-либо из условий ветвей.
Полнота вычислений #
Если when используется как выражение, то ветка else является обязательной, за
исключением случаев, в которых компилятор может убедиться, что ветки покрывают
все возможные значения
Так происходит, например с записями классов-перечислений
enum class Bit {
ZERO, ONE
}
val numericValue = when (getRandomBit()) {
Bit.ZERO -> 0
Bit.ONE -> 1
// 'else' не требуется, потому что все случаи учтены
}В операторах when ветка else является обязательной в следующих условиях:
- when имеет объект типа
Boolean,enum,sealedили ихnullable-аналоги - ветки when не охватывают все возможные случаи для этого объекта