? Does one or both guarantee that the output will be non-null?
m
Michael Krussel
05/13/2024, 7:50 PM
In the first example
T
can be a nullable type and the compile will force you to handle the possible
null
return from
foo
.
I think the default type inference will be the non null, but you can force it.
null.foo<Any?>()
will have a return type of
Any?
s
Sam
05/13/2024, 7:50 PM
In the first example, T can be any type, nullable or otherwise, and additionally, the receiver can be null even if T is given as a non null type. The return type is nullable if and only if T is given as nullable. Whereas in the second example, T must be non null, so the return type must be non null (but the receiver is nullable)
👍 2
s
Sam Stone
05/13/2024, 8:06 PM
@Sam I don't understand: isn't the type of T the same as the type of the receiver? How can the type be non-nullable if the receiver is nullable? Only by explicitly declaring the type in brackets?
m
Michael Krussel
05/13/2024, 8:07 PM
The receiver will still be
nullable
with the second version, but
T
will not be so the return type will not be.
s
Sam
05/13/2024, 8:09 PM
The receiver type is
T?
, so no, it's not the same as
T
. The added
?
means it can always be null, even if
T
itself is a non-null type.
e
ephemient
05/13/2024, 8:10 PM
Kotlin will infer the narrowest type reasonable, but with the first, both
Copy code
val x: String?
x.foo<String>()
x.foo<String?>()
are possible. with the second, only
Copy code
x.foo<String>()
is possible. (well plus supertypes, so
x.foo<Any>()
etc. may also be possible)
👍 1
s
Stephan Schröder
05/14/2024, 8:06 AM
but this version should be equivalent to the second, isn't it?