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