Kotlin let není if

Konstrukce ?.let {} ?: run {} se sice používá jakoby místo if - else, ale není s ní zaměnitelná. Pokud máte nullable objekt, použitím ?.let {} zpracujete případ, kdy je not null a ?: run {} v případě, že je null. Dalo by se říct, klasické if – else. Níže je ukázka. Vytvoříme outer a inner mapu, inicializujeme jí a pak máme dva bloky. První s if – else a druhý s ?.let a ?: run. V blocích jde o to, že nejdříve se zkusí vytáhnout hodnota pro klíč z outer mapy a pokud je hodnota nalezena, totéž proběhne pro inner mapu.

fun main() {
    val outerMap = mapOf(
        Pair(1L, "A"),
        Pair(2L, "B")
    )
    val innerMap = mapOf(
        Pair(1L, "AA")
    )

    val key = 1L

    val ifResult = if (outerMap[key] != null) {
        println("outer value for key $key found")
        if (innerMap[key] != null) {
            println("inner value for key $key found")
            "Ok"
        } else {
            println("inner value for key $key NOT found")
            null
        }
    } else {
        println("outer value for key $key NOT found")
        throw IllegalArgumentException("Required key $key not found")
    }
    println(ifResult)

    val letResult = outerMap[key]
        ?.let {
            println("outer value for key $key found")
            innerMap[key]
                ?.let {
                    println("inner value for key $key found")
                    "Ok"
                }
                ?: run {
                    println("inner value for key $key NOT found")
                    null
                }
        }
        ?: run {
            println("outer value for key $key NOT found")
            throw IllegalArgumentException("Required key $key not found")
        }
    println(letResult)
}

Pokud kód spustíte, asi vás nepřekvapí následující výpis.

outer value for key 1 found
inner value for key 1 found
Ok

outer value for key 1 found
inner value for key 1 found
Ok

Pokud ale hodnotu val key změníte na 2, bude výpis následující.

outer value for key 2 found
inner value for key 2 NOT found
null

outer value for key 2 found
inner value for key 2 NOT found
outer value for key 2 NOT found
Exception in thread "main" java.lang.IllegalArgumentException: Required key 2 not found
	at cz.vitfo.StrangeKt.main(Strange.kt:190)
	at cz.vitfo.StrangeKt.main(Strange.kt)

Blok s ?.let ?: run proběhl odlišně. V inner mapě nebyla hodnota nalezena a vrátila se null. Jelikož ?.let blok skončil null, přešlo se do bloku ?: run. Zde je to ukázáno zjednodušeně.

fun main() {
    val str: String? = "some string"
    str
        ?.let {
            println("not null")
            null
        }
        ?: run { 
            println("null")
        }
}

Výsledek

not null
null

Napsat komentář