Let confusion


If I understand correctly when you use let it should run the code in the block if the condition is true but I am finding inconsistency with that so I wrote the following simple code to test it out…

    val str = ""

    str.isNotEmpty().let {
        println("is not empty")

    str.isEmpty().let {
        println("is empty")

The results were…

is not empty
is empty

So what I am wondering is how it can be both empty and not empty at the same time?


Calls the specified function block with this value as its argument and returns its result.



str.isEmpty().let { check ->
    println("is empty: $check")


I guess what I am trying to do is…

    if (str.isNotEmpty()) {

As a default it starts as empty and gets late initialised and thats what i am checking.

It sounds like the let block happens and has nothing to do with true or false

I heard of the ?.let check for not null and wrongly assumed it would work this way when linked to isNotEmpty()


Just as you say. T.let{…} has nothing to do with true or false.


let is used to check null

str?.let {
  print("str is not null")


One way to do that is to combine it with takeIf or takeUnless (which were introduced in Kotlin 1.1):

str.takeIf{ it.isNotEmpty() }?.let { }

Probably not a good replacement in this case, but it is useful for filtering in a long string of chained method calls sometimes.

See: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/take-if.html


Technically, it is not let that is checking the null but the safe call operator (?.)