I have a generic interface which accepts all kinds of values, I cannot declare the generic type as
out
since the
get()
accepts this same type as a parameter:
interface MyInterface<T> {
val inner: T
fun get(other: T): String
}
I want this interface to be iterable when the generic type is also an iterable, so I add this extension function:
operator fun <T> MyInterface<Iterable<T>>.iterator(): Iterator<T> = TODO()
However, when using this interface, I cannot iterate over it:
fun doSomething(payload: MyInterface<Set<Any>>) {
for (row in payload) { /* ... */ }
^ COMPILE ERROR: For-loop range must have an 'iterator()' method
}
If I declare the generic type as
out
, the compiler no longer complains about a missing
iterator()
method, but the
MyInterface::get(T)
method cannot compile anymore since the generic type is
out
(while also used as an
in
by this method).
From what I understand, it seems that
Kotlin accepts to iterate over a type even if it doesn’t explicitly implement the
Iterable<T>
interface,
as long as an iterator(): Iterator<T>
method exists. However, it doesn’t seem to work when the generic type is not defined as
out
, despite being both
in
and
out
here in my first example.
Am I missing/abusing something or is this a bug in the language?