Kotlin Check Multiple Variables for Not Null (Let)

Oct 4, 2019

In the following example, null checking is not valid as person is mutable.

class Test {    fun printPerson(name: String, age: Int) {        Timber.d("name=$name, age=$age")    }    var person = Person()    fun test() {        if (person.name != null && person.age != null) {            printPerson(person.name, person.age)        }    }}

Solution 1: Local Variable

val name = person.nameval age = person.ageif (name != null && age != null) {    printPerson(name, age)}

Solution 2: Nested Let

person.name?.let { name ->    person.age?.let { age ->        printPerson(name, age)    }}

Solution 3

This solution by Dario Pellegrini has some overheads, and doesn't work well when the variables are of different types.

inline fun <T: Any> ifLet(vararg elements: T?, closure: (List<T>) -> Unit) {    if (elements.all { it != null }) {        closure(elements.filterNotNull())    }}
ifLet (person.name, person.age) { (name, age) ->    printPerson(name as String, age as Int)}

Solution 4

This solution by Jayson Minard seems to have little overheads, but need to create multiple extensions to support different number of variables (but 5 should be enough for most cases).

// 2 variablesfun <T1: Any, T2: Any, R: Any> safeLet(p1: T1?, p2: T2?, block: (T1, T2)->R?): R? {    return if (p1 != null && p2 != null) block(p1, p2) else null}// 3 variablesfun <T1: Any, T2: Any, T3: Any, R: Any> safeLet(p1: T1?, p2: T2?, p3: T3?, block: (T1, T2, T3)->R?): R? {    return if (p1 != null && p2 != null && p3 != null) block(p1, p2, p3) else null}// 4 variablesfun <T1: Any, T2: Any, T3: Any, T4: Any, R: Any> safeLet(p1: T1?, p2: T2?, p3: T3?, p4: T4?, block: (T1, T2, T3, T4)->R?): R? {    return if (p1 != null && p2 != null && p3 != null && p4 != null) block(p1, p2, p3, p4) else null}// 5 variablesfun <T1: Any, T2: Any, T3: Any, T4: Any, T5: Any, R: Any> safeLet(p1: T1?, p2: T2?, p3: T3?, p4: T4?, p5: T5?, block: (T1, T2, T3, T4, T5)->R?): R? {    return if (p1 != null && p2 != null && p3 != null && p4 != null && p5 != null) block(p1, p2, p3, p4, p5) else null}
safeLet(person.name, person.age) { name, age ->    printPerson(name, age)}

References:

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.