Kotlin genéricos para los Consumidores solamente

Eugene:

Vamos a decir que tengo este ejemplo de Java:

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

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

Nótese como el segundo parámetro se declara ? super T. Necesito esto porque quiero llamar a ese método como este:

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

Ahora estoy tratando de lograr lo mismo con Kotlin (que tengo muy poca experiencia con):

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

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

Y ahora que estoy tratando de usarlo:

fun main(args: Array<String>) {

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

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

Curiosamente, esto no falla (a menos que sepa muy poco sobre Kotlin aquí).

Me esperaba que tengo que añadir a la declaración algo así como Sink<in T>dejar que el compilador sabe que esto es realmente solo una Consumer, o es in Tsiempre, de manera predeterminada?

¿Puede alguien que conoce Kotlin mejor que yo, me punto en la dirección correcta?

Jorn Vernee:

Como dije en mi comentario, Testá siendo inferido como Anyaquí. Eso es lo que veo cuando dejando que mi IDE añadir argumentos de tipo explícitas a la drainToSinkllamada.

Desde Kotlin de Listes estrictamente un productor, porque es inmutable, que declara que es el parámetro tipo que out E. Se obtiene List<Any>como un tipo de parámetro para drainToSink, y está bien asignar una List<String>a lo siguiente:

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

Si cambia el primer tipo de parámetro a MutableList<T>, que no tiene un parámetro de tipo covariante, su ejemplo no falte;

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

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=191549&siteId=1
Recomendado
Clasificación