Hi,
I have a problem with the usage of the `Lists.filterNotNull() extension.
The function is described as follows:
Copy code
public fun <T : Any> Iterable<T?>.filterNotNull(): List<T> {
return filterNotNullTo(ArrayList<T>())
}
So I expect I can use it with a non-nullable list with nullable items, and I get a non-nullable list with just non-nullable items back.
But when I use this method like so:
Copy code
fun List<String?>?.extract(): List<String> =
this?.filterNotNull().map {
"foo"
}.toList()
I get a compiler error as shown in my screenshot.
Why is this the case? I would have expected that the output is a non-nullable list, at least that is what I read out of the signature?
I am using kotlin 1.3.72
☑️ 1
b
bezrukov
08/25/2020, 11:19 AM
So I expect I can use it with a non-nullable list with nullable items
this is correct
But the issue is that you wrote an extension for nullable list (List<String?>*?*)
d
dmitriy.novozhilov
08/25/2020, 11:19 AM
Call with safe operator
?.
returns nullable object
Correct code for your case should look smth like this:
Copy code
fun List<String?>?.extract(): List<String> =
this?.filterNotNull()?.map { "foo" } ?: emptyList()
h
huehnerlady
08/25/2020, 11:23 AM
I thought the ? returns null if it is null and otherwise continues with a smartcasted non-nullable type?
huehnerlady
08/25/2020, 11:23 AM
as I use
this?.filterNotNull()
it should be smartcasted to a non-nullable object when calling the filter function I thought?
d
dmitriy.novozhilov
08/25/2020, 11:28 AM
No, there is no such smartcasts. If they will exist then there will be ambiguities for functions with nullable receivers
Consider such case:
Copy code
fun Int?.foo(): String = "hello"
fun Int.foo(): String = "world"
fun test(s: String?) {
val message = s?.length.foo()
println(message)
// what should be printed?
// "hello", "world" or "null"?
// currently it is unequivocally prints "hello"
}
h
huehnerlady
08/25/2020, 11:29 AM
ok, I missunderstood then, many thanks for your help 🙂