Reputation: 33880
I have a bunch of beans that have nullable properties like so:
package myapp.mybeans;
data class Foo(val name : String?);
And I have a method in the global space like so:
package myapp.global;
public fun makeNewBar(name : String) : Bar
{
...
}
And somewhere else, I need to make a Bar
from the stuff that's inside Foo
. So, I do this:
package myapp.someplaceElse;
public fun getFoo() : Foo? { }
...
val foo : Foo? = getFoo();
if (foo == null) { ... return; }
// I know foo isn't null and *I know* that foo.name isn't null
// but I understand that the compiler doesn't.
// How do I convert String? to String here? if I do not want
// to change the definition of the parameters makeNewBar takes?
val bar : Bar = makeNewBar(foo.name);
Also, doing some conversion here with foo.name
to cleanse it every time with every little thing, while on the one hand provides me compile-time guarantees and safety it is a big bother most of the time. Is there some short-hand to get around these scenarios?
Upvotes: 51
Views: 38620
Reputation: 7293
You could use an extension:
fun <T> T?.default(default: T): T {
return this ?: default
}
Then use it like this:
fun getNonNullString(): String {
return getNullableString().default("null")
}
Upvotes: 7
Reputation: 41678
You need double exclamation mark like so:
val bar = makeNewBar(foo.name!!)
As documented in Null Safety section:
The third option is for NPE-lovers. We can write b!!, and this will return a non-null value of b (e.g., a String in our example) or throw an NPE if b is null:
val l = b!!.length
Thus, if you want an NPE, you can have it, but you have to ask for it explicitly, and it does not appear out of the blue.
Upvotes: 56