Kotlin Academy · Pelajaran

Penyarangan dan Penggabungan Hierarki Sealed

Bina mesin keadaan kompleks dengan menyarangkan jenis sealed.

Pelajaran 4 daripada 413 langkah

Penyarangan dan Penggabungan Hierarki Sealed ialah pelajaran Kotlin Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Kotlin Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Kotlin Academy merangkumi sejumlah 4 pelajaran.

Menggubah Pepohon Keadaan

Keadaan dunia sebenar selalunya mempunyai beberapa dimensi. Sarangkan jenis sealed atau gabungkan hierarki berasingan untuk memodelkan domain kompleks dengan kemas.

Kelas Sealed Bersarang

Isytiharkan jenis sealed anak di dalam jenis sealed luar. Pengkompil masih menguatkuasakan kelengkapan merentasi keseluruhan pepohon.

sealed class UiState {
    object Loading : UiState()
    sealed class Loaded : UiState() {
        data class Success(val items: List<String>) : Loaded()
        data class Empty(val message: String) : Loaded()
    }
    data class Error(val msg: String) : UiState()
}
fun render(s: UiState) = when (s) {
    UiState.Loading -> "loading"
    is UiState.Loaded.Success -> "${s.items.size} items"
    is UiState.Loaded.Empty -> "empty: ${s.message}"
    is UiState.Error -> "err: ${s.msg}"
}
fun main() {
    println(render(UiState.Loaded.Success(listOf("a", "b"))))
}

Antara Muka Sealed untuk Mixin

Gunakan antara muka sealed apabila suatu keadaan mempunyai beberapa aspek ortogon — setiap aspek menggunakan antara muka yang berbeza.

sealed interface Authenticated
data class User(val id: Int) : Authenticated
object Guest
sealed interface Permission
object Read : Permission
object Write : Permission
fun describe(a: Authenticated, p: Permission): String = when {
    a is User && p is Write -> "user ${a.id} can write"
    a is User -> "user ${a.id} can read"
    else -> "?"
}
fun main() {
    println(describe(User(1), Write))
}

Menggabungkan Hierarki

Hantar dua nilai sealed dan tukar berdasarkan gabungannya — gunakan when dengan syarat.

sealed class Theme { object Light : Theme(); object Dark : Theme() }
sealed class Lang { object En : Lang(); object Tr : Lang() }
fun greet(theme: Theme, lang: Lang) = when {
    theme is Theme.Dark && lang is Lang.Tr -> "Karanlik Merhaba"
    theme is Theme.Light && lang is Lang.Tr -> "Aydinlik Merhaba"
    theme is Theme.Dark -> "Dark Hello"
    theme is Theme.Light -> "Light Hello"
    else -> "?"
}
fun main() {
    println(greet(Theme.Dark, Lang.Tr))
}

Mesin Keadaan dengan Variasi Bersarang

Modelkan aliran kerja berbilang langkah sebagai jenis sealed bersarang — setiap langkah mempunyai variasinya sendiri.

sealed class Checkout {
    object Start : Checkout()
    sealed class Payment : Checkout() {
        object Pending : Payment()
        data class Failed(val reason: String) : Payment()
        object Captured : Payment()
    }
    object Shipped : Checkout()
    object Delivered : Checkout()
}
fun describe(c: Checkout) = when (c) {
    Checkout.Start -> "starting"
    Checkout.Payment.Pending -> "awaiting payment"
    is Checkout.Payment.Failed -> "payment failed: ${c.reason}"
    Checkout.Payment.Captured -> "paid"
    Checkout.Shipped -> "shipped"
    Checkout.Delivered -> "delivered"
}
fun main() {
    println(describe(Checkout.Payment.Failed("card declined")))
}

Menggunakan Semula Hierarki Sealed Merentas Modul

Jenis sealed paling sesuai ditakrifkan mengikut modul. Untuk gubahan merentas modul, dedahkan antara muka sealed supaya setiap modul boleh menambah pelaksanaan sendiri.

sealed interface Notification
data class Email(val to: String) : Notification
data class Sms(val phone: String) : Notification
fun send(n: Notification) = when (n) {
    is Email -> "sending email to ${n.to}"
    is Sms -> "texting ${n.phone}"
}
fun main() {
    println(send(Email("a@example.com")))
}

Sifat Base Sepunya

Kelas sealed boleh mengisytiharkan sifat sepunya — semua subtype mewarisinya. Ini mengekalkan keadaan dan metadata DRY.

sealed class HttpResponse(val code: Int) {
    class Ok(val body: String) : HttpResponse(200)
    class NotFound(val path: String) : HttpResponse(404)
    class ServerError(val cause: String) : HttpResponse(500)
}
fun describe(r: HttpResponse) = "[${r.code}] " + when (r) {
    is HttpResponse.Ok -> r.body
    is HttpResponse.NotFound -> "not found: ${r.path}"
    is HttpResponse.ServerError -> "fail: ${r.cause}"
}
fun main() {
    println(describe(HttpResponse.Ok("hello")))
}

Memodelkan Pepohon Rekursif

Jenis sealed menerangkan struktur rekursif seperti pepohon ungkapan secara semula jadi.

sealed class Expr {
    data class Num(val value: Int) : Expr()
    data class Add(val left: Expr, val right: Expr) : Expr()
    data class Mul(val left: Expr, val right: Expr) : Expr()
}
fun eval(e: Expr): Int = when (e) {
    is Expr.Num -> e.value
    is Expr.Add -> eval(e.left) + eval(e.right)
    is Expr.Mul -> eval(e.left) * eval(e.right)
}
fun main() {
    val expr = Expr.Add(Expr.Num(3), Expr.Mul(Expr.Num(4), Expr.Num(5)))
    println(eval(expr)) // 23
}

Menggabungkan dengan Generik

Jenis sealed boleh bersifat generik, lalu membolehkan sampul hasil yang ditaip seperti Result<T>.

sealed class ApiResult<out T> {
    data class Success<T>(val data: T) : ApiResult<T>()
    data class Failure(val message: String) : ApiResult<Nothing>()
}
fun handle(r: ApiResult<String>) = when (r) {
    is ApiResult.Success -> "got ${r.data}"
    is ApiResult.Failure -> "err: ${r.message}"
}
fun main() {
    println(handle(ApiResult.Success("hi")))
    println(handle(ApiResult.Failure("nope")))
}

Antipola: Pensarangaan Terlalu Dalam

Pensarangaan yang dalam menyembunyikan maksud. Jika pepohon sealed mempunyai lebih daripada 2 aras, pertimbangkan untuk meratakannya atau mengekstrak subpepohon ke dalam failnya sendiri.

sealed class Top {
    sealed class Mid : Top() {
        sealed class Deep : Mid() {
            object Leaf : Deep()
        }
    }
}
fun main() {
    val l = Top.Mid.Deep.Leaf
    println(l::class.simpleName)
}

Menggabungkan melalui Komposisi

Apabila dua dimensi keadaan adalah bebas, utamakan komposisi (kelas data yang membungkus dua nilai sealed) berbanding hierarki yang bersarang terlalu dalam.

sealed class Loading { object Active : Loading(); object Idle : Loading() }
sealed class Auth { data class Signed(val id: Int) : Auth(); object Anon : Auth() }
data class AppState(val loading: Loading, val auth: Auth)
fun main() {
    val s = AppState(Loading.Active, Auth.Signed(1))
    println(s)
}

Semakan Pantas

Apakah pendekatan yang disyorkan apabila dua dimensi keadaan adalah bebas?

Imbas Kembali

Sarangkan jenis sealed untuk keadaan berbentuk pepohon; gabungkan hierarki sealed yang bebas menggunakan komposisi (kelas data pembungkus). Tambahkan sifat sepunya pada Base sealed, gunakan generik untuk hasil bertipe, dan modelkan struktur rekursif secara semula jadi. Pastikan pensarangaan tidak terlalu dalam.

Percuma untuk bermula

Pelajari Kotlin dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
51
Pelajaran
203

Soalan Lazim

Adakah pelajaran “Penyarangan dan Penggabungan Hierarki Sealed” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Kotlin Academy, termasuk “Penyarangan dan Penggabungan Hierarki Sealed”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Kotlin Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Penyarangan dan Penggabungan Hierarki Sealed”?

Bina mesin keadaan kompleks dengan menyarangkan jenis sealed. Anda berlatih Kotlin Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Kotlin Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Kotlin Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Penyarangan dan Penggabungan Hierarki Sealed” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Kotlin Academy ini?

Ya. Setiap pelajaran Kotlin Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. sealed class berbanding sealed interface: Bila Hendak Menggunakan Setiap Satu
  2. when Menyeluruh dengan Hierarki Sealed
  3. Memodelkan Keadaan UI dengan Sealed Class
  4. Penyarangan dan Penggabungan Hierarki Sealed
← Kembali ke Kotlin Academy