Функция Kotlin для печати всех пар порядковый номер/имя Enum

Что-то в Enums меня смущает. Я хотел бы, чтобы функция «знала» обо всех возможных сопоставлениях порядкового номера/имени Enum, но передача моего класса перечисления в функцию работает неправильно.

fun printEnumOrdinalAndNames(targetEnumType:???)

Я могу взломать его на вызывающей стороне с помощью

println(MY_ENUM_TYPE.values().map { it.ordinal to it.name }.toMap())

но я не уверен, смогу ли я каким-то образом передать MY_ENUM_TYPE::class или что-то подобное, я не могу получить сигнатуру функции, чтобы принять любое перечисление. printEnumOrdinalAndNames(MY_ENUM_TYPE) не будет компилироваться, потому что это недопустимый синтаксис.

Как создавать пользовательские общие типы в Python (50/100 дней Python)
Как создавать пользовательские общие типы в Python (50/100 дней Python)
Помимо встроенных типов, модуль типизации в Python предоставляет возможность определения общих типов, что позволяет вам определять типы, которые могут...
1
0
48
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете написать функцию с типом reified, чтобы сделать это на любом Enum. Когда у вас есть класс, вы можете сопоставить его enumContstants с чем угодно (в данном случае с Map<String,Int>) или изменить его, чтобы распечатать их, если хотите.

inline fun <reified T : Enum<*>> namesAndOrdinalsOf(): Map<String,Int> =
    T::class.java.enumConstants.map {
        it.name to it.ordinal
    }.toMap()

Редактировать: Я понятия не имел, что enumValues<T>() существует (спасибо @Slaw), вы можете переписать это так, так как это проще:

inline fun <reified T : Enum<T>> namesAndOrdinalsOf(): Map<String,Int> =
    enumValues<T>().map {
        it.name to it.ordinal
    }.toMap()

И использовать его:

enum class Things {
    Grapes,
    Chairs,
    Spectacles
}

fun main() {
    println(namesAndOrdinalsOf<Things>())
}
// Prints: {Grapes=0, Chairs=1, Spectacles=2}

Очевидно, я не знаю, как использовать reified. Отлично сработало, спасибо!

Benjamin H 13.05.2019 19:59

Вы можете использовать enumValues() для получения констант произвольного enum, как описано в Классы Enum — язык программирования Kotlin. Для этого требуется встроенная функция с овеществленным типом:

inline fun <reified T : Enum<T>> ordinalsAndNamesOf() =
    enumValues<T>().map { it.ordinal to it.name }.toMap()

И его использование будет выглядеть так:

fun main() {
    println(ordinalsAndNamesOf<Foo>())
}

enum class Foo {
    BAR, BAZ, QUX
}

Другие вопросы по теме