ProgrammazioneSviluppatore Backend

Che cos'è lo smart casting in Kotlin? Come funziona con le condizioni, l'espressione when, i tipi nullable, i getter personalizzati e le proprietà? Fai esempi e sottigliezze.

Supera i colloqui con l'assistente IA Hintsage

Risposta.

Smart casting è un meccanismo in cui il compilatore Kotlin "abbassa" automaticamente il tipo dopo aver verificato un certo tipo o null. Questo consente di utilizzare le proprietà e i metodi del tipo in cui è stato effettuato il casting senza conversione esplicita.

Esempio:

fun demo(x: Any) { if (x is String) { println(x.length) // x è automaticamente castato a String } }

Funziona con:

  • operatori is / !is (ad esempio, in if o when)
  • variabili nullable (if (x != null))
  • espressioni when

Non funziona:

  • Quando la proprietà ha un getter personalizzato (il compilatore perde la certezza che il valore non sia cambiato tra il controllo e l'uso)
  • Per proprietà open/var della classe

Esempio con nullable:

val str: String? = getString() if (str != null) println(str.length) // smart cast

Quando non funziona:

val something: Any get() = fetch() if (something is String) { println(something.length) // Errore: smart cast non possibile }

Domanda ingannevole.

È possibile contare su smart cast per proprietà open o var della classe all'interno dei metodi?

No! Smart cast funziona solo con variabili locali e proprietà val nelle classi finali. Per proprietà open o var, il compilatore non è sicuro che il valore possa cambiare da altri thread o da sottoclassi. Per loro è necessario un cast manuale o una variabile locale.

open class Base { open var maybeString: Any? = "abc" fun check() { if (maybeString is String) { // println(maybeString.length) // Errore: Smart cast non possibile val asString = maybeString as String println(asString.length) // Cast esplicito } } }

Esempi di errori reali a causa della scarsa comprensione delle sottigliezze dell'argomento.


Storia

In un progetto, per la logica degli schermi, sono state utilizzate proprietà model open var. Il programmatore si aspettava di ottenere smart-cast dopo il controllo if (model is SomeType), ma durante la compilazione ha dovuto fare tutto manualmente, il che ha peggiorato la leggibilità e ha aumentato la duplicazione del codice a causa della mancata conoscenza delle limitazioni di smart cast su var/open.


Storia

Quando si ottenevano dati tramite un getter (ad esempio, attraverso un delegato o una validazione), lo smart cast non ha funzionato. Lo sviluppatore non ha compreso le ragioni e ha impiegato diverse ore per il debug, finché non ha scoperto che il compilatore non applica smart cast a tali getter, poiché possono restituire valori diversi tra le chiamate.


Storia

In un progetto, durante l'elaborazione di valori nullable tramite if (obj != null) lo smart cast ha funzionato all'interno del ramo, mentre parallelizzando il codice si sono verificati NullPointerException a causa di accessi al di fuori dell'area di garanzia. Questo ha mostrato una comprensione insufficiente dell'azione locale di smart cast e delle peculiarità degli scenari multithread di lavoro con variabili nullable.