Kotlin扩展为下一个Enum值而没有反射

时间:2017-02-17 22:38:34

标签: enums kotlin

我写了一个Kotlin扩展,为枚举值添加了next()。但是有更好的方法吗?

fun <T : Enum<*>> T.next(): T {
    val values = this::class.java.getEnumConstants()
    return if (this.ordinal < values.size - 1) 
            values[this.ordinal + 1] 
        else 
            values[0]
}
enum class Color {Red, Yellow, Green}
Color.Red.next() //Yellow
  1. 我可以在没有反思的情况下实现这一目标吗?
  2. 如果没有,如何用Kotlins反射做到这一点?
  3. 想法是从枚举值迭代到下一个。但仅限于特定值,而不是整个枚举values()列表。我想要阻止的是为每个枚举类型添加以下内容:

    fun next() = if (this.ordinal == Color.values().size - 1) 
            Color.values()[0] 
        else 
            Color.values()[this.ordinal + 1]
    

1 个答案:

答案 0 :(得分:2)

你可以在没有反映的情况下做到这一点(目前你可以尝试the 1.1 RC build)使用enumValues<T>(),它不使用里面的反射,因为它在调用网站上内联,而且相应的enum类型在编译时放在生成的代码中。例如:

inline fun <reified T: Enum<T>> T.next(): T {
    val values = enumValues<T>()
    val nextOrdinal = (ordinal + 1) % values.size
    return values[nextOrdinal]
}

(demo of this code) | inlinereified是必需的,因为enumValues<T>()reified T

与Kotlin 1.0.6一起使用的替代方案(但仍使用Java反射中的getDeclaringClass()):

fun <T: Enum<T>> T.next(): T {
    val values = declaringClass.enumConstants
    val nextOrdinal = (ordinal + 1) % values.size
    return values[nextOrdinal]
}