Ce face is, !is și smart cast
x is Tip întoarce true dacă valoarea x este de tipul Tip (sau de un subtip al lui). !is este negația. Se folosește cu valori de tip general (Any, o interfață, o clasă sealed) ca să afli ce sunt de fapt.
Smart cast: după ce ai verificat tipul cu is (sau ai verificat x != null), compilatorul tratează automat variabila ca având tipul verificat, fără conversie manuală. Funcționează în if, în ramurile lui when, după && și după un return timpuriu: if (x !is String) return, apoi x.length.
Smart cast merge doar când compilatorul e sigur că valoarea nu se poate schimba între verificare și folosire: variabile val locale, parametri, proprietăți val din același modul fără getter propriu. La o proprietate var, copiază întâi valoarea într-o val locală.
Ce returnează
Boolean.
Exemple
Exemplul 1: Tipuri diferite într-o listă
Lista conține valori de tip Any. După is String, se poate folosi direct .length; după is Int, înmulțirea.
fun descrie(x: Any): String = when (x) {
is String -> "text cu ${x.length} caractere"
is Int -> "număr întreg, dublul este ${x * 2}"
is Double -> "număr real, rotunjit ${Math.round(x)}"
is List<*> -> "listă cu ${x.size} elemente"
else -> "alt tip: ${x::class.simpleName}"
}
fun main() {
val valori: List<Any> = listOf("Iași", 21, 9.75, listOf(1, 2, 3), true)
for (v in valori) {
println(descrie(v))
}
}
Rezultat
text cu 4 caractere
număr întreg, dublul este 42
număr real, rotunjit 10
listă cu 3 elemente
alt tip: Boolean
Exemplul 2: Smart cast după && și după return
În dreapta lui &&, valoare este deja String. După if (... !is ...) return, tipul rămâne cunoscut până la finalul funcției.
fun esteCodPostal(valoare: Any): Boolean =
valoare is String && valoare.length == 6 && valoare.all { it.isDigit() }
fun aplicaReducere(pret: Any) {
if (pret !is Double) {
println("prețul trebuie să fie Double, am primit $pret")
return
}
println("cu 10% reducere: ${pret * 0.9} lei")
}
fun main() {
println(esteCodPostal("700259"))
println(esteCodPostal(700259))
aplicaReducere(50.0)
aplicaReducere("50")
}
Rezultat
true
false
cu 10% reducere: 45.0 lei
prețul trebuie să fie Double, am primit 50
Exemplul 3: Smart cast pe null și proprietăți var
Verificarea != null face și ea smart cast. Proprietatea var se copiază într-o val locală, altfel compilatorul refuză smart cast-ul.
class Comanda(var observatii: String?)
fun main() {
val c = Comanda("sună la interfon")
val obs = c.observatii // copie locală
if (obs != null) {
println("Observații (${obs.length} caractere): $obs")
}
val nume: String? = listOf("Ana", "Dan").firstOrNull { it.startsWith("D") }
if (nume != null && nume.length > 2) {
println("Primul nume cu D: ${nume.uppercase()}")
}
}
Rezultat
Observații (16 caractere): sună la interfon
Primul nume cu D: DAN
Greșeli frecvente
- Smart cast pe o proprietate
var: eroareaSmart cast to 'String' is impossible, because 'observatii' is a mutable property that could be mutated concurrently. Copiază valoarea într-ovallocală. x is List<String>: tipul elementelor nu se păstrează la rulare (type erasure). Poți verifica doarx is List<*>.- Verificarea unui tip pe care compilatorul îl știe deja (
"text" is String): dă avertismentulcheck for instance is always 'true'.
Comenzi înrudite
as și as? (conversie de tip): as tratează o valoare ca alt tip (aruncă excepție dacă nu se potrivește); as? întoarce null în loc de excepție.when: Alege o ramură după valoarea unei expresii sau după prima condiție adevărată; înlocuiește switch din alte limbaje.null și null safety (?. ?: !!): null înseamnă „nicio valoare”. Kotlin separă tipurile care acceptă null (String?) și oferă ?., ?: și !! pentru ele.sealed class și sealed interface: sealed declară o ierarhie închisă: toate subtipurile sunt cunoscute la compilare, deci when le poate verifica pe toate fără else.