Generics Kotlin:枚举上的泛型迭代器:如何声明类型变量

Generics Kotlin:枚举上的泛型迭代器:如何声明类型变量,generics,enums,kotlin,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++

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

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++]
}
类枚举迭代器:迭代器 { 私有变量游标=0 override fun hasNext():布尔=光标<枚举值()。大小-1 重写fun next():T=enumValues()[cursor++] } IntelliJ IDE将两个枚举值中的T标记为红色:

“无法将'T'用作具体化类型参数。请改用类。”


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

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


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

如果需要迭代器,为什么不直接使用
AnyEnumClass.values().iterator()

而不使用具体化类型
enum类示例{
A、 B、C、D
}
有趣的迭代器(值:()->数组):迭代器=值()
.asIterable()
.iterator()
趣味主线(args:Array){
val迭代器=迭代器(示例::值)
迭代器.forEach{
println(it)
}
}
这是通过使用函数而不是包装类来实现的,根据您的使用情况,它可能是一个更好的选择

具体化类型
enum类示例{
A、 B、C、D
}
inline fun iterator():iterator=enumValues().iterator()
趣味主线(args:Array){
val迭代器=迭代器()
迭代器.forEach{
println(it)
}
}

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

要确认,您需要获取一个迭代器,其中T是一个枚举类型,它的值经过迭代?最好简化为
有趣的迭代器(值:数组):迭代器
迭代器(例如.values())
枚举值().iterator()
而不是
T::class.java.enumConstants.iterator()
?使用这种精确的代码是不可能的,问题是如何使其成为可能。
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)
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++]
}
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)
    }
}