Kotlin 密封类的代数数据类型与协变逆变对抗
掌握 sealed class 作为代数数据类型的完整表达力,以及如何用声明处变型解决模式匹配中的类型安全问题。 · 难度:入门 · +10XP
密封类的代数数据类型与协变逆变对抗
密封类是 Kotlin 实现代数数据类型的利器,但当遇到泛型协变时,模式匹配分支可能出现类型泄漏。本教程将展示如何利用声明处变型(out/in)让密封子类保留类型参数信息,避免 when 表达式中的强制转型。同时探讨递归密封接口如何定义类似链表的结构,并在编译期保证穷尽性检查。你将学会用密封类建模 JSON 节点、表达式树等复杂领域模型。
sealed interface Tree<out T> {
data class Leaf<T>(val value: T) : Tree<T>
data class Node<T>(val left: Tree<T>, val right: Tree<T>) : Tree<T>
}
fun <T> Tree<T>.depth(): Int = when(this) {
is Tree.Leaf -> 1
is Tree.Node -> maxOf(left.depth(), right.depth()) + 1
}
fun main() {
val tree: Tree<Int> = Tree.Node(Tree.Leaf(1), Tree.Leaf(2))
println(tree.depth()) // 2
}