【问题标题】:Get enum value based on it's ordinal in a generic class根据泛型类中的序数获取枚举值
【发布时间】:2020-05-16 08:14:25
【问题描述】:

考虑下面的代码:

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() 中的序数返回枚举值?
  • 我希望E.values() 可用,但它不在泛型类中?

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

【问题讨论】:

    标签: generics kotlin


    【解决方案1】:

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

    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))
    }
    

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

    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 关键字的精彩解释由 answer 给出。

    我希望 E.values() 可用,但它不在 泛型类?

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

    【讨论】:

    • 很好的答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多