when แบบครอบคลุมทุกกรณีกับลำดับชั้น Sealed
เขียนนิพจน์ when ที่ครอบคลุม sealed ทุกรูปแบบอย่างครบถ้วน
when แบบครอบคลุมทุกกรณีกับลำดับชั้น Sealed เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
นิพจน์เงื่อนไขที่ครอบคลุมทุกกรณี
นิพจน์ when ที่ใช้เป็นนิพจน์ต้อง ครอบคลุมทุกกรณี ซึ่งหมายถึงต้องจัดการค่าที่เป็นไปได้ทุกค่า ลำดับชั้นแบบปิดผนึกช่วยให้คอมไพเลอร์ตรวจสอบสิ่งนี้แทนคุณได้
นิพจน์เงื่อนไขที่ไม่ครอบคลุมบนชนิดเปิด
สำหรับคลาสทั่วไป คอมไพเลอร์ไม่สามารถตรวจสอบชนิดย่อยทั้งหมดได้ จึงต้องมีแขนง 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())) }นิพจน์เงื่อนไขที่ครอบคลุมบนชนิดแบบปิดผนึก
สำหรับคลาสแบบปิดผนึก คอมไพเลอร์ทราบชนิดย่อยทั้งหมด หากครอบคลุมทุกกรณีแล้ว ก็ไม่จำเป็นต้องใช้ else
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 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()))
}การแปลงประเภทอัจฉริยะในแขนงเงื่อนไข
ภายในแต่ละแขนง is Kotlin จะเปลี่ยนชนิดของตัวแปรเป็นชนิดเฉพาะให้โดยอัตโนมัติ จึงไม่ต้องแปลงชนิดด้วยตนเอง
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')))
}การลืมกรณีหนึ่ง
หากเพิ่มรูปแบบใหม่ในภายหลัง นิพจน์ when ที่ครอบคลุมทุกกรณีและยังใช้ชนิดแบบปิดผนึกเป็นนิพจน์จะคอมไพล์ไม่ผ่าน นี่คือกลไกช่วยเพิ่มความปลอดภัยที่ยอดเยี่ยม
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 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")))
}การใช้ when เป็นคำสั่ง
เมื่อใช้ when เป็นคำสั่ง (ไม่ใช่นิพจน์) ก็ไม่จำเป็นต้องครอบคลุมทุกกรณี แต่คุณจะสูญเสียกลไกช่วยเพิ่มความปลอดภัยนี้
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) }บังคับตรวจสอบความครอบคลุมของคำสั่ง
กำหนดค่าให้กับ when (หรือใช้เทคนิค .exhaustive) เพื่อให้คอมไพเลอร์บังคับให้ครอบคลุมทุกกรณี
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) }แขนงหลายกรณี
จัดกลุ่มกรณีด้วยเครื่องหมายจุลภาค เพื่อใช้เนื้อหาของแขนงร่วมกันกับหลายรูปแบบ
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())) }ชนิดแบบปิดผนึกซ้อนกัน
ลำดับชั้นแบบปิดผนึกสามารถซ้อนกันได้ และการตรวจสอบความครอบคลุมยังทำงานกับต้นไม้ที่มีหลายระดับ
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))
}ตรวจสอบอย่างรวดเร็ว
ประโยชน์หลักของการใช้ when กับลำดับชั้นแบบปิดผนึกคืออะไร
ทบทวน
ใช้คลาสหรืออินเทอร์เฟซแบบปิดผนึกร่วมกับ when เพื่อตรวจสอบความครอบคลุมตั้งแต่เวลาคอมไพล์ การแปลงประเภทอัจฉริยะช่วยให้เนื้อหาในแขนงต่าง ๆ เรียบง่าย ใช้เป็นนิพจน์ (หรือกำหนดผลลัพธ์ให้ตัวแปร) เพื่อบังคับการตรวจสอบ จัดกลุ่มกรณีด้วยเครื่องหมายจุลภาค และซ้อนชนิดแบบปิดผนึกเพื่อสร้างสถานะรูปต้นไม้
คำถามที่พบบ่อย
บทเรียน “when แบบครอบคลุมทุกกรณีกับลำดับชั้น Sealed” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “when แบบครอบคลุมทุกกรณีกับลำดับชั้น Sealed” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “when แบบครอบคลุมทุกกรณีกับลำดับชั้น Sealed”
เขียนนิพจน์ when ที่ครอบคลุม sealed ทุกรูปแบบอย่างครบถ้วน คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “when แบบครอบคลุมทุกกรณีกับลำดับชั้น Sealed” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม
ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- sealed class กับ sealed interface: ควรใช้แบบใด
- when แบบครอบคลุมทุกกรณีกับลำดับชั้น Sealed
- จำลองสถานะ UI ด้วย Sealed Class
- การซ้อนและรวมลำดับชั้น Sealed