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