My (non compiling) code for a generic iterator over enumerations is as follows:
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++]
}
The IntelliJ IDE marks the T in both enumValues< T > red:
"Cannot use 'T' as reified type parameter. Use a class instead."
How to declare the type parameters to get rid of the error?
Since Kotlin enums are classes, they can have their own properties, methods, and implement interfaces.
If a generic type has several type parameters, each of them can be projected independently. For example, if the type is declared as interface Function<in T, out U> you could use the following star-projections: Function<*, String> means Function<in Nothing, String> . Function<Int, *> means Function<Int, out Any?> .
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)
}
}
This works by using a function instead of a wrapper class, depending on your use it may be a better option.
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)
}
}
This requires the type to be explicitly set, but does not need a reference to the values method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With