In Kotlin, data conversion commonly appears as interpreting a value as another type. An explicit cast uses `as`; a smart cast combines an `is` check with compiler-provided conversion, reducing redundant code while preserving safety. section 2.3.6
Prefer a smart cast after a type check
interface Expr class Num(val value: Int) : Expr fun eval(e: Expr): Int { if (e is Num) { return e.value } throw IllegalArgumentException("Unknown expression") } The `is Num` check lets `e.value` work without writing `e as Num`. The compiler permits this only when the value cannot change after the check, such as a stable `val` property without a custom accessor. section 2.3.6
Choose the conversion form according to the information available at runtime:
- Use `is` when branching on a known type; Kotlin can then smart-cast the value inside the branch. section 2.3.6
- Use `as` for an explicit cast when the expected type is certain; use `as?` when a failed conversion should produce `null`. section 2.3.6 section 11.2.1
- Do not rely on runtime checks for generic type arguments: type erasure prevents distinguishing `List<String>` from `List<Int>`. section 11.2.1
- Use `List<*>` to check that a value is some kind of list without claiming its element type. section 11.2.1
A safe cast still needs validation
fun printSum(c: Collection<*>) { val intList = c as? List<Int> ?: throw IllegalArgumentException("List is expected") println(intList.sum()) } This accepts `listOf(1, 2, 3)` but rejects a set. A list containing strings can still produce a `ClassCastException`, because erased generic information cannot fully verify the element type at runtime. section 11.2.1
Listing 2.18 Evaluating expressions with an if cascade
fun eval(e: Expr): Int {
if (e is Num) {
val n = e as Num #1
return n.value
}
if (e is Sum) {
return eval(e.right) + eval(e.left) #2
}
throw IllegalArgumentException("Unknown expression")
}
fun main() {
println(eval(Sum(Sum(Num(1), Num(2)), Num(4))))
// 7
}
Inspect the complete expression evaluator to see explicit casting replaced by smart-cast access in a runnable example. section 2.3.6




















