https://kotlinlang.org logo
Title
r

robstoll

03/13/2019, 8:55 PM
is there a way to turn a type parameter with upper bound
Any?
into its non-nullable variant? I would like to avoid something like:
fun <T: Any> foo(t: T?)
s

streetsofboston

03/13/2019, 8:57 PM
fun <T : Any> foo(t: T?)
would do that, wouldn’t it?
r

robstoll

03/13/2019, 8:57 PM
that's the solution I don't want (ah my mistake forgot to add
Any
as upper bound
p

pavel

03/13/2019, 8:58 PM
I am not sure I understand what you are trying to do
s

streetsofboston

03/13/2019, 8:58 PM
Then I’m not sure what you want.
fun <T> foo(t: T)
would be the one you want…
p

pavel

03/13/2019, 8:59 PM
you can do
fun <T:Any?> foo(t:T)
s

streetsofboston

03/13/2019, 8:59 PM
But
: Any?
is the default if you omit it
r

robstoll

03/13/2019, 8:59 PM
fun <T> foo(t: T){ if(t != null) bar(t) //compile error } fun <T: Any> bar(t: T){}
for instance
s

streetsofboston

03/13/2019, 9:01 PM
I see, it’s the other way around 🙂
fun <T> foo(t: T){
 if(t != null) bar<Any>(t) // no compile error
}

fun <T: Any> bar(t: T){}
p

pavel

03/13/2019, 9:04 PM
fun <T : Any> foo(t: T?) {
    if (t != null)
        bar(t) //no compile error
}

fun <T : Any> bar(t: T) {}
works as well
s

streetsofboston

03/13/2019, 9:04 PM
@pavel But then
bar
can no longer accept null-values…. I assumed that the signature of the functions can’t change, only their implementation
p

pavel

03/13/2019, 9:05 PM
fun <T: Any> bar(t: T){}
it never could
💯 1
s

streetsofboston

03/13/2019, 9:07 PM
Ooops… I meant ‘foo’…. and still that one can accept null values 🙂 Still, the signature of the function(s) change…
p

pavel

03/13/2019, 9:08 PM
yeah, if that change is prohibited then my solution doesn’t work
r

robstoll

03/13/2019, 9:08 PM
ok, take it to a next level,
bar<Any>
doesn't help in my case because guess what, bar takes a second parameter:
fun <T: Any> bar(t: T, a: A<T>){}
s

streetsofboston

03/13/2019, 9:09 PM
Then if the signatures can change, Pavel has the right solution.
p

pavel

03/13/2019, 9:10 PM
fun <T : Any> foo(t: T?) {
    if (t != null)
        bar(t, emptyList()) //no compile error
}

fun <T : Any> bar(t: T, f: List<T>) {}
r

robstoll

03/13/2019, 9:11 PM
haha... you come up with nice examples, this does of course not work if List would not be covariant
A
might not be covariant
but I see, in some situations the fallback to
Any
makes sense 🙂
oh... and you used
fun <T : Any> foo(t: T?)
which I want to stay away from if possible
s

streetsofboston

03/13/2019, 9:14 PM
interface A<T>

fun <T : Any> foo(t: T?) {
    if (t != null)
        bar(t, object: A<T>{}) //no compile error
}

fun <T : Any> bar(t: T, f: A<out T>) {}
And changing
out
to
in
or nothing still works fine.
Why don’t you want to use
fun <T : Any> foo(t: T?)
?
r

robstoll

03/13/2019, 9:15 PM
you have to define every single api using it like this then
it pollutes your api
s

streetsofboston

03/13/2019, 9:16 PM
I see… If it were
fun <T : Any> foo(t: T?) : T
then this is a nice way of providing the generic, but since
foo
doesn’t return a T type, you api gets a bit polluted.
r

robstoll

03/13/2019, 9:17 PM
say you have another function
baz
which wants to use foo, now it has to use the workaround with
T: Any
and
T?
as well... but I guess I have to go this way until the new type inference is in place
I think I saw in a talk that this will be solved then
p

pavel

03/13/2019, 9:19 PM
or you could just stop accepting
null
params 😉
😁 1
r

robstoll

03/13/2019, 9:19 PM
yeah.. unfortunately I have to
btw. thanks for your time 🙂
i

ilya.gorbunov

03/13/2019, 11:16 PM
@robstoll New inference will provide the way to do it, but the current one doesn't have any.