Kotlin:Enum上的通用迭代器:如何声明类型变量

Min*_*eet 4 generics enums kotlin

我的枚举泛型迭代器的(非编译)代码如下:

class EnumIterator<T: Enum<T>>: Iterator<T> 
{
   private var cursor = 0

   override fun hasNext(): Boolean = cursor < enumValues<T>().size - 1
   override fun next(): T = enumValues<T>()[cursor++]
}
Run Code Online (Sandbox Code Playgroud)

IntelliJ IDE将两个enumValues <T>中T标记为红色:

“不能将'T'用作化类型参数。请改用类。”

如何声明类型参数以摆脱错误?

Ale*_*nov 5

您需要将类显式传递给构造函数(并且可以有一个工厂函数来避免在调用站点使用它):

class EnumIterator<T: Enum<T>>(clazz: Class<T>): Iterator<T> {
   private var cursor = 0
   // your original code gets them on each hasNext/next call
   private val values = clazz.enumConstants

   override fun hasNext(): Boolean = cursor < values.size - 1
   override fun next(): T = values[cursor++]
}

// factory function 
inline fun <reified T: Enum<T>> EnumIterator(): EnumIterator<T> = EnumIterator(T::class.java)
Run Code Online (Sandbox Code Playgroud)

如果您不需要EnumIterator将其设置为本地类型,您也可以稍微简化它(编辑:@jrtapsell 的“使用具体化类型”解决方案更好):

inline fun <reified T: Enum<T>> EnumIterator(): Iterator<T> = object : Iterator<T> {
    private var cursor = 0
    private val values = enumValues<T>()

    override fun hasNext(): Boolean = cursor < values.size - 1
    override fun next(): T = values[cursor++]
}
Run Code Online (Sandbox Code Playgroud)


jrt*_*ell 5

没有类型化

enum class Example {
    A, B, C, D
}

fun <T: Enum<T>> iterator(values:()->Array<T>):Iterator<T> = values()
    .asIterable()
    .iterator()

fun main(args: Array<String>) {

    val iterator = iterator(Example::values)

    iterator.forEach {
        println(it)
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以通过使用函数而不是包装器类来实现,根据您的使用情况,它可能是一个更好的选择。

带化型

enum class Example {
    A, B, C, D
}

inline fun <reified T: Enum<T>> iterator():Iterator<T> = enumValues<T>().iterator()

fun main(args: Array<String>) {

    val iterator = iterator<Example>()

    iterator.forEach {
        println(it)
    }
}
Run Code Online (Sandbox Code Playgroud)

这要求显式设置类型,但不需要引用values方法。