Kotlin函数可打印所有Enum的序数/名称对

时间:2019-05-13 17:26:50

标签: generics kotlin 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)无法编译,因为它不是有效的语法。

2 个答案:

答案 0 :(得分: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}

答案 1 :(得分:1)

您可以使用enumValues()来获取任意enum的常量,如Enum Classes - Kotlin Programming Language中所述。它需要一个内联函数,其类型为以下类型:

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
}