https://kotlinlang.org logo
Title
t

tapchicoma

02/19/2019, 3:38 PM
Why does this work:
fun bar(): Single<List<Number>> {
    return Single.just(listOf<Int>())
}
But this doesn't (
type mismatch
):
fun bar(): Single<List<Number>> {
    val foo = Single.just(listOf<Int>())
    return foo
}
Removing
Single
or changing to:
fun bar(): Single<List<Number>> {
    val foo = Single.just<List<Number>>(listOf<Int>())
    return foo
}
solves the issue 🤔
s

streetsofboston

02/19/2019, 3:46 PM
Variance.
Single
is defined as *in*variant:
public abstract class Single<T> ...
That means that in your 2nd example, this line
val foo = Single.just(listOf<Int>())
reads like
val foo: Single<List<Int>> = Single.just(listOf<Int>())
and since Single’s generic-param is invariant, a
Single<List<Int>>
is not a subclass of
Single<List<Number>>
If Single was defined as
class Single<out E> ...
your 2nd example would compile. E.g. replace
Single
with `Single2`:
class Single2<out E> {
    companion object {
        fun <E> just(value: E) : Single2<E> {
            TODO()
        }
    }
}
The 3rd example, you explicitly upcast your return value
foo
. The 1st example, though, is different. I guess it can infer the upcast there, but not in the 2nd. That is somewhat odd.
t

tapchicoma

02/19/2019, 3:52 PM
changing to
fun bar(): Single<out List<Number>>() { .. }
also solves the issue, so seems you are right