Kotlin扩展,无需反射即可获得下一个Enum值

Tob*_*bse 2 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
Run Code Online (Sandbox Code Playgroud)
  1. 我能在没有思考的情况下实现这一目标吗?
  2. 如果没有,如何用Kotlins反射来做到这一点?

想法是从枚举值迭代到下一个值。但仅适用于特定值,不适用于整个枚举values()列表。我要防止的事情是在每个枚举类型中添加以下内容:

fun next() = if (this.ordinal == Color.values().size - 1) 
        Color.values()[0] 
    else 
        Color.values()[this.ordinal + 1]
Run Code Online (Sandbox Code Playgroud)

hot*_*key 5

您可以使用来在Kotlin 1.1中进行反射而不进行反射(当前,您可以尝试使用1.1 RC buildenumValues<T>(),该方法没有在内部使用反射,因为它是内联在调用站点上的,并且相应的enum类型已放置在结果代码中在编译时。例:

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

(此代码的演示) | 在inlinereified需要,因为enumValues<T>()reified T

与Kotlin 1.0.6兼容的替代方法(但仍getDeclaringClass()从Java反射中使用):

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