Reputation: 3370
This is working :
val values: List<String> = listOf("a", null, "b").filterNotNull()
This is not working :
fun <A> nonNullValues(values: List<A?>): List<A> = values.filterNotNull()
The compiler complains about generic types :
Error:(8, 63) Kotlin: Type parameter bound for T in fun <T : kotlin.Any> kotlin.collections.Iterable<T?>.filterNotNull(): kotlin.collections.List<T>
is not satisfied: inferred type A is not a subtype of kotlin.Any
This one is working :
fun <A: Any> nonNullValues(values: List<A?>): List<A> = values.filterNotNull()
Could someone please explain me why I need to tell the compiler that A is a subtype of Any? I was thinking every type was a subtype of Any...
Thanks!
Upvotes: 5
Views: 810
Reputation: 41608
As per the Kotlin docs:
The default upper bound (if none specified) is
Any?
This means that the problematic declaration is equivalent to:
fun <A:Any?> nonNullValues(values: List<A?>): List<A> = values.filterNotNull()
The nonNullValues
method declares to return a list of nullable items of type A
whereas filterNotNull
returns a list of non nullable items of type A
. Hence a mismatch and a compiler error.
Upvotes: 7