Distinguish universal values, no result, and no return
Any is a supertype of non-null Kotlin values; Any? also admits null. Unit represents a function completing without a meaningful result. Nothing has no instances and describes a computation that never returns normally, such as one that always throws.
fun fail(message: String): Nothing = throw IllegalArgumentException(message)
fun name(value: Any?): String {
val text = value as? String ?: fail("Expected text")
return text.trim()
}
fun announce(text: String): Unit {
println(text)
}
The safe cast as? returns null when a value has the wrong type. The unsafe cast as throws on an incompatible value. Because fail never returns, the compiler can treat text as a non-null string after the Elvis expression.
A function returning Unit can finish successfully. A function returning Nothing cannot. Confusing these types leads to APIs that promise normal completion but always fail.
Exercise
Implement a safe integer extractor returning Int? from Any?, then a required extractor that throws a descriptive exception.
Check: null, a string containing digits, and an actual integer should follow three explicitly understood cases; casting a string does not parse it.