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++]
}

IntelliJ IDE 在两个枚举值中都标记了 T红色:

"不能使用'T'作为化类型参数。改用类。

如何声明类型参数以消除错误?

没有化类型

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

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

带化型

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

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

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

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)

如果您不需要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++]
}

enumValues 是一个内联函数,因此必须在编译时知道其化参数的确切类型,这在您的情况下是不可能的。

如果您需要迭代器,为什么不只做AnyEnumClass.values().iterator()

最新更新