Safe Call and Elvis

Nullable Types, the Safe Call and Elvis Operators

The safe call a?.b evaluates b only when a is not null and yields null otherwise, so a chain collapses at the first gap. The Elvis operator a ?: b (tilt your head to see the quiff) supplies b when a is null, and because return and throw are expressions, its right side can also leave the function:

safecall.kt: labels for BookNest books with missing dataKotlin
data class Book(val id: Int, val title: String, val subtitle: String? = null)
val catalog = listOf(Book(1, "The Quiet Harbor"),
    Book(2, "Patterns of the Deep Web", "How Services Talk"))
fun find(id: Int): Book? = catalog.find { it.id == id }
fun label(id: Int): String {
    val book = find(id) ?: return "No book #$id"      // Elvis with an early return
    return "${book.title}: ${book.subtitle?.lowercase() ?: "no subtitle"}"
}
fun main() {
    listOf(1, 2, 99).forEach { println(label(it)) }
    println(find(99)?.subtitle?.length)                 // the whole chain yields null
}
Output
The Quiet Harbor: no subtitle
Patterns of the Deep Web: how services talk
No book #99
null

After the guard, book has the non-null type Book, so the rest of label() needs no checks. To run a block only when a value exists, write x?.let { ... } (Scope Functions). Unlike ||, ?: reacts only to null, never to 0, "" or false.