kotlin generics for Consumer only

Eugene :

Let' say i have this java example:

interface Sink<T> {
    void accumulate(T t);
}

public static <T> void drainToSink(Collection<T> collection, Sink<? super T> sink) {
    collection.forEach(sink::accumulate);
}

Notice how the second parameter is declared to be ? super T. I need this because I want to call that method like this:

Sink<Object> sink = .... // some Sink implementation
Collection<String> strings = List.of("abc");
drainToSink(strings, sink);

Now I am trying to achieve the same thing with kotlin (which I have very small experience with):

interface Sink<T> {
    fun accumulate(t: T)
}

fun <T> drainToSink(collection: List<T>, sink: Sink<T>) {
   ....
}

And now I am trying to use it:

fun main(args: Array<String>) {

     val sink = object : Sink<Any> {
         override fun accumulate(any: Any) {  }
     }

     val strings = emptyList<String>()
     drainToSink(strings, sink)
}

Interestingly enough, this does not fail (unless I know too little about kotlin here).

I was really expecting that I need to add to the declaration something like Sink<in T> to let the compiler know that this is actually just a Consumer, or is in T always on, by default?

Can someone who knows kotlin better than me, point me in the right direction?

Jorn Vernee :

Like I said in my comment, T is being inferred as Any here. That's what I see when letting my IDE add explicit type arguments to the drainToSink call.

Since kotlin's List is strictly a producer, because it is immutable, it declares it's type parameter as out E. You get List<Any> as a parameter type for drainToSink, and it's fine to assign a List<String> to that:

val strings = emptyList<String>()
val x: List<Any> = strings // works

If you change the first parameter type to MutableList<T>, which does not have a covariant type parameter, your example does fail:

fun <T> drainToSink(collection: MutableList<T>, sink: Sink<T>) {
    ....
}
val strings = emptyList<String>()
drainToSink(strings, sink) // type mismatch: Required: MutableList<Any>, Found: List<String>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=82015&siteId=1