Home > Enterprise >  Kotlin and ?.let: how to choose variants of variable's fields?
Kotlin and ?.let: how to choose variants of variable's fields?

Time:07-26

I have a class:

class Clazz(
    val name: String?,
    val value0: String,
    val value1: String?,
    val value2: String
)

I want to print value0 if we have non-null name. But if name is null, then i want return value1 only if it is not null. if it is, return value2.

i do it in let way:

val result =
            clazz.name?.let {
                return clazz value0
            } ?: run {
                value1 ?: value2
            }

but i think it is quite shitty code and it could be done better and simplier. Is it such a way?

CodePudding user response:

Try below code it will work:

Code:

val result: String = when {
            clazz.name.isNullOrEmpty() -> {
                clazz.value1 ?: clazz.value2
            }
            else -> {
                clazz.value0
            }
        }

Explanation:

val result: String = when {
            // check name is null --> true
            clazz.name.isNullOrEmpty() -> {

                // check value1 is not null, if null then return value2

                clazz.value1 ?: clazz.value2 
            }
            else -> { // name is not nul so it will return value0
                clazz.value0
            }
        }

CodePudding user response:

You basically have a situation where you have a list of alternatives (value0, value1, value2), and you want to pick the first alternative that is non null. value0 doesn't quite fit into this, but we can make it fit by using ?.let as in your attempt, or in general, make any condition fit using takeIf.

Then you can just write your alternatives and separate them with the elvis operator ?::

clazz.value0.takeIf { clazz.name != null } ?: // or clazz.name?.let { clazz.value0 }
clazz.value1 ?:
clazz.value2

You can also extract out clazz into a run:

clazz.run {
    value0.takeIf { name != null } ?: 
    value1 ?: 
    value2
}

This reads just like English:

Take value0 if name is not null, otherwise value1 if it is not null. Otherwise value2.

CodePudding user response:

In Kotlin, if can be used as an expression (like when). And it's often more readable than ?.let {..} ?: run {..}. You could use it this way:

val result = if (clazz.name != null) {
    clazz.value0 
} else {
    clazz.value1 ?: clazz.value2
}

Now, as is often the case, isolated pieces of logic like this are best extracted into a separate function. So I would suggest extracting this piece in an extension function on Clazz:

val result = clazz.meaningfulNameForThis()


private fun Clazz.meaningfulNameForThis() = if (name != null) {
    value0 
} else {
    value1 ?: value2
}
  • Related