0Pricing
Kotlin Academy · Lekcja

Kompletne when z hierarchiami sealed

Pisz kompletne wyrażenia when obejmujące każdy wariant sealed.

Kompletne when z hierarchiami sealed to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Wyczerpujące when

Wyrażenie when użyte jako wyrażenie musi być wyczerpujące — musi obsługiwać każdą możliwą wartość. Hierarchie sealed pozwalają kompilatorowi zweryfikować to za Państwa.

Niewyczerpujące when dla typu otwartego

W przypadku zwykłych klas kompilator nie może sprawdzić wszystkich podtypów — wymaga gałęzi 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())) }

Wyczerpujące when dla sealed

W przypadku sealed class kompilator zna wszystkie podtypy. else nie jest potrzebne, jeśli uwzględniono każdy przypadek.

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

Interfejsy sealed zapewniają sprawdzanie kompletności nawet wtedy, gdy klasy wymagają wielokrotnego dziedziczenia.

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 casty w gałęziach

Wewnątrz każdej gałęzi is Kotlin automatycznie rzutuje zmienną na konkretny typ — nie trzeba wykonywać rzutowania ręcznie.

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')))
}

Pominięcie przypadku

Jeśli później zostanie dodany nowy wariant, każde wyczerpujące when, które nadal używa typu sealed jako wyrażenia, przestanie się kompilować — to świetne zabezpieczenie.

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 z klasami data

Typowy wzorzec: klasy data jako warianty hierarchii 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")))
}

Używanie when jako instrukcji

Użyte jako instrukcja (a nie wyrażenie), when nie musi być wyczerpujące. Tracą Państwo jednak wtedy to zabezpieczenie.

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) }

Wymuszanie sprawdzania kompletności instrukcji

Należy przypisać when do wartości (albo użyć sztuczki z .exhaustive), aby kompilator wymusił uwzględnienie wszystkich przypadków.

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) }

Gałęzie obejmujące wiele przypadków

Przypadki można grupować za pomocą przecinków, aby współdzieliły treść dla wielu wariantów.

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())) }

Zagnieżdżone typy sealed

Hierarchie sealed mogą być zagnieżdżane — sprawdzanie kompletności nadal działa w głębokich drzewach.

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))
}

Szybkie sprawdzenie

Jaka jest główna korzyść z używania when z hierarchiami sealed?

Podsumowanie

Klasy i interfejsy sealed należy łączyć z when, aby uzyskać sprawdzaną podczas kompilacji kompletność. Smart casty upraszczają treść gałęzi. Należy używać when jako wyrażenia (albo przypisać jego wynik), aby wymusić sprawdzanie; przypadki można grupować przecinkami, a typy sealed zagnieżdżać, aby modelować stan w kształcie drzewa.

Często zadawane pytania

Czy lekcja „Kompletne when z hierarchiami sealed” jest bezpłatna?

Tak — pełny tekst „Kompletne when z hierarchiami sealed” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Kompletne when z hierarchiami sealed”?

Pisz kompletne wyrażenia when obejmujące każdy wariant sealed. Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?

Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Kompletne when z hierarchiami sealed”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?

Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. sealed class a sealed interface: kiedy używać każdej z nich
  2. Kompletne when z hierarchiami sealed
  3. Modelowanie stanu interfejsu za pomocą klas sealed
  4. Zagnieżdżanie i łączenie hierarchii sealed
← Powrót do Kotlin Academy