Extension to ?.let syntax

I often use ?.let {} for simple null checks, but I’m wondering if the following syntax would ever be feasible in the language:

myVar?.let {
    it.doSomething()
} else {
    // Do something else because myVar is null
}

Why not use this?:

if (myVar != null) {
    myVar.doSomething()
} else {
    // Do something else because myVar is null
}

It’s a common Kotlin code-smell to replace a short null check with ?.let {}.
Many people (myself included) experience a ?.let {} phase when learning Kotlin.

3 Likes

The main use would be when myVar is mutable and Kotlin tells you the value may have changed, so it can’t smartcast inside the if block.

1 Like

Instead of let you can use also and instead of else the Elvis operator:

myVar?.also {
    it.doSomething()
} ?: {
    // Do something else because myVar is null
}
2 Likes

Note that you will need to use run { ... } to execute the code withi the code block, otherwise it’s just a lambda.

2 Likes

You are right, as the question states doSomething instead of getSomething.
When the code would say getSomething, your approach doesn’t work anymore.

The best approach would then be to assign the receiver to a local variable.

You can also write the following function:

inline fun <T : Any, S> T?.mapNullable(
    notNull: (T) -> S,
    onNull : () -> S
) = when(this){
   null -> onNull()
   else -> notNull(this)
}

Then you can rewrite

myVar?.let {
    it.computePresentValue()
} else {
    it.computeAbsentValue()
}

to

val t = myVar.mapNullable(
    notNull = { it.computePresentValue() },
    onNull = { it.computeAbsentValue() }
)

I fail to se how that is better than

val t = when (val it = myVar) {
    null -> computeAbsentValue()
    else -> it.computeAbsentValue()
}
2 Likes

It isn’t. Yours is best.
Just didn’t think about it…