0Pricing
Kotlin Academy · Lezione

when esaustivo con gerarchie sealed

Scriva espressioni when complete che gestiscano ogni variante sealed.

when esaustivo con gerarchie sealed è una lezione Kotlin Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Kotlin Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Kotlin Academy include 4 lezioni in totale.

when esaustivo

Un'espressione when utilizzata come espressione deve essere esaustiva: deve gestire ogni valore possibile. Le gerarchie sealed consentono al compilatore di verificarlo al posto Suo.

when non esaustivo su un tipo open

Per le classi ordinarie, il compilatore non può verificare tutti i sottotipi e richiede un ramo else.

open class Shape
class Circle : Shape()
class Square : Shape()
fun describe(s: Shape) = when (s) {
    is Circle -> "circle"
    is Square -> "square"
    else      -> "unknown" // required
}
fun main() { println(describe(Circle())) }

when esaustivo su un tipo sealed

Per una sealed class, il compilatore conosce tutti i sottotipi. Non è necessario else se ogni caso è gestito.

sealed class Result
class Success(val value: Int) : Result()
class Failure(val msg: String) : Result()
fun describe(r: Result) = when (r) {
    is Success -> "ok: ${r.value}"
    is Failure -> "err: ${r.msg}"
}
fun main() {
    println(describe(Success(42)))
    println(describe(Failure("nope")))
}

Sealed interface

Le sealed interface offrono il controllo di esaustività anche quando le classi necessitano di ereditarietà multipla.

sealed interface Animal
class Dog : Animal
class Cat : Animal
fun speak(a: Animal) = when (a) {
    is Dog -> "woof"
    is Cat -> "meow"
}
fun main() {
    println(speak(Dog()))
    println(speak(Cat()))
}

Smart cast nei rami

All'interno di ogni ramo is, Kotlin applica automaticamente uno smart cast alla variabile, convertendola nel tipo specifico: non è necessario alcun cast manuale.

sealed class Event
data class Click(val x: Int, val y: Int) : Event()
data class Key(val char: Char) : Event()
fun handle(e: Event) = when (e) {
    is Click -> "clicked at (${e.x},${e.y})" // smart-cast
    is Key   -> "key=${e.char}"
}
fun main() {
    println(handle(Click(10, 20)))
    println(handle(Key('A')))
}

Dimenticare un caso

Se in seguito aggiunge una nuova variante, ogni when esaustivo che utilizza ancora il tipo sealed come espressione non verrà compilato: è un'eccellente rete di sicurezza.

sealed class Status
object Idle : Status()
object Running : Status()
// If we add object Done : Status(), every exhaustive when must update.
fun text(s: Status): String = when (s) {
    is Idle -> "idle"
    is Running -> "running"
}
fun main() { println(text(Idle)) }

Sealed con data class

Un modello comune consiste nell'utilizzare data class come varianti di una gerarchia sealed.

sealed class UiState {
    object Loading : UiState()
    data class Success(val data: List<String>) : UiState()
    data class Error(val message: String) : UiState()
}
fun render(state: UiState) = when (state) {
    UiState.Loading -> "loading..."
    is UiState.Success -> "got ${state.data.size} items"
    is UiState.Error -> "error: ${state.message}"
}
fun main() {
    println(render(UiState.Loading))
    println(render(UiState.Success(listOf("a", "b"))))
    println(render(UiState.Error("404")))
}

Utilizzare when come istruzione

Quando viene utilizzato come istruzione (non come espressione), when non deve essere esaustivo. Tuttavia, si rinuncia alla rete di sicurezza.

sealed class Cmd
object Start : Cmd()
object Stop : Cmd()
fun execute(c: Cmd) {
    // Statement form: no error if incomplete (avoid this style)
    when (c) {
        Start -> println("started")
        Stop -> println("stopped")
    }
}
fun main() { execute(Start); execute(Stop) }

Forzare il controllo di esaustività su un'istruzione

Assegni when a un valore (oppure utilizzi il trucco .exhaustive) in modo che il compilatore imponga la gestione di tutti i casi.

sealed class Cmd
object Start : Cmd()
object Stop : Cmd()
fun execute(c: Cmd) {
    val handled: Unit = when (c) { // expression context now
        Start -> println("started")
        Stop -> println("stopped")
    }
}
fun main() { execute(Start) }

Rami con più casi

Raggruppi i casi separandoli con virgole per condividere il corpo tra più varianti.

sealed class Event
class Click : Event()
class Tap : Event()
class Drag : Event()
fun isPointer(e: Event) = when (e) {
    is Click, is Tap, is Drag -> true
}
fun main() { println(isPointer(Tap())) }

Tipi sealed annidati

Le gerarchie sealed possono essere annidate: il controllo di esaustività continua a funzionare anche su alberi profondi.

sealed class Network {
    sealed class Wifi : Network() {
        object Open : Wifi()
        data class Secured(val ssid: String) : Wifi()
    }
    object Cellular : Network()
}
fun describe(n: Network) = when (n) {
    Network.Wifi.Open -> "open wifi"
    is Network.Wifi.Secured -> "secured: ${n.ssid}"
    Network.Cellular -> "cellular"
}
fun main() {
    println(describe(Network.Wifi.Secured("home")))
    println(describe(Network.Cellular))
}

Verifica rapida

Qual è il vantaggio principale dell'utilizzo di when con le gerarchie sealed?

Riepilogo

Abbini sealed class/interface a when per ottenere l'esaustività verificata in fase di compilazione. Gli smart cast semplificano i corpi dei rami. Utilizzi when come espressione (oppure assegni il risultato) per forzare il controllo; raggruppi i casi con le virgole e annidi i tipi sealed per rappresentare stati strutturati ad albero.

Domande Frequenti

La lezione «when esaustivo con gerarchie sealed» è gratuita?

Sì — il testo completo di «when esaustivo con gerarchie sealed» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Kotlin Academy, passa a CoddyKit PRO. Il corso Kotlin Academy include 4 lezioni in totale.

Cosa imparerò in «when esaustivo con gerarchie sealed»?

Scriva espressioni when complete che gestiscano ogni variante sealed. Eserciti Kotlin Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Kotlin Academy?

Non è richiesta alcuna esperienza precedente. Kotlin Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «when esaustivo con gerarchie sealed»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Kotlin Academy?

Sì. Ogni lezione Kotlin Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. sealed class e sealed interface: quando usare ciascuna
  2. when esaustivo con gerarchie sealed
  3. Modellare lo stato dell'interfaccia con le sealed class
  4. Annidare e combinare gerarchie sealed
← Torna a Kotlin Academy