Smart Casts with Nullable Types

Null Checks are Smart Casts Too

After if (x != null), a String? becomes String inside the branch. The same happens after ?: return, which is the most common pattern in Kotlin functions.

Example

data class Address(val city: String?, val pin: String?)

fun shippingLabel(name: String?, address: Address?): String {
    if (name == null) return "Missing name"
    val addr = address ?: return "Missing address for $name"   // addr is Address
    val city = addr.city ?: "Unknown city"
    return if (addr.pin != null && addr.pin.length == 6) "$name, $city - ${addr.pin}"
           else "$name, $city (PIN missing)"
}

fun main() {
    println(shippingLabel("Asha", Address("Hyderabad", "500081")))
    println(shippingLabel("Ravi", Address(null, null)))
    println(shippingLabel("Kiran", null))
    println(shippingLabel(null, null))
}

Output

Asha, Hyderabad - 500081
Ravi, Unknown city (PIN missing)
Missing address for Kiran
Missing name

Exercise

Exercise: Write fun total(items: List<Any?>): Int that adds Ints directly, adds the length of Strings and ignores everything else (including null).

Show answer
fun total(items: List<Any?>): Int {
    var sum = 0
    for (x in items) {
        when (x) {
            is Int -> sum += x
            is String -> sum += x.length
        }
    }
    return sum
}

fun main() {
    println(total(listOf(5, "abc", null, 2.5, 10))) // 18
}