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

时间:2018-04-16 10:38:58

标签: 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++]
}

IntelliJ IDE在 enumValues&lt; 中标记 T 。 T&gt; 红色:

  

“不能使用'T'作为改进的类型参数。请改用类。”

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

3 个答案:

答案 0 :(得分:4)

没有具体型

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方法。

答案 1 :(得分:3)

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

PIC 9(10)V99

如果你不需要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) 作为一个单独的类型,你也可以稍微简化这一点(编辑:@ jrtapsell的“使用reified type”解决方案更好):

EnumIterator

答案 2 :(得分:1)

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

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