关于Kotlin:根据泛型类中的序数获取枚举值

Get enum value based on it's ordinal in a generic class

考虑以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class SegmentController<E : Enum<E>>() {

    fun getEnumForOrdinal(ordinal: Int) : E {
        //values is undefined?
        //how can I return the enum for the specified ordinal value?
        return E.values()[ordinal]
    }

    fun getOrdinalForEnum(enum: E): Int {
        //no problem getting the ordinal from the supplied E enum
        return enum.ordinal
    }

}

它是一个通用类,以任何Enum作为模板。

  • 如何基于getEnumForOrdinal()中的序数返回Enum值?
  • 我希望E.values()可用,但是它不在通用类之内?

我进行了研究,但找不到基于序数的任何解决方案,我发现了这些链接:

  • 如何从Kotlin中的枚举类和字符串获取原始类型的枚举值
  • 从枚举序数转换为枚举类型

您可以将枚举的类作为构造函数参数传递,并通过enumConstants

访问枚举值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class SegmentController<E : Enum<E>>(private val clazz: Class<E>) {

    fun getEnumForOrdinal(ordinal: Int): E {
        return clazz.enumConstants[ordinal]
    }

    fun getOrdinalForEnum(e: Enum<E>): Int {
        return e.ordinal
    }
}

enum class SEGMENTS {A, B, C}

fun main() {
    val controller = SegmentController(SEGMENTS::class.java)
    println(controller.getOrdinalForEnum(SEGMENTS.B))
    println(controller.getEnumForOrdinal(1))
}

或者,您可以将getEnumForOrdinal定义为带有reified类型参数Einline函数,并使用enumValues访问枚举的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class SegmentController<E : Enum<E>>() {

    inline fun <reified E : Enum<E>> getEnumForOrdinal(ordinal: Int): E {
        return enumValues<E>()[ordinal]
    }

    fun getOrdinalForEnum(e: Enum<E>): Int {
        return e.ordinal
    }
}

enum class SEGMENTS {A, B, C}

fun main() {
    val controller = SegmentController<SEGMENTS>()
    println(controller.getOrdinalForEnum(SEGMENTS.B))
    println(controller.getEnumForOrdinal<SEGMENTS>(1))
}

另请参见:https://kotlinlang.org/docs/reference/enum-classes.html#working-with-enum-constants

此答案给出了reified关键字的出色解释。

I would expect the E.values() to be available, but its not inside the
generic class?

values()方法在Enum类中不可用。