Kotlin密封类嵌套泛型实现及任务状态类型不匹配问题求解
问题根因
原实现的类型不匹配错误来自泛型绑定错误:
- 原代码将
TaskStatus.InProgress硬编码声明为TaskStatus<NoResult>类型,泛型参数被固定为NoResult - 该实例只能赋值给要求
TaskStatus<NoResult>类型的Task.A,无法满足Task.B对TaskStatus<TaskBResult>的类型要求 - 本质错误是给「进行中」这个本来不关联任何结果的状态,错误绑定了固定的结果泛型
调整后的数据模型
核心修改是让InProgress适配任意结果泛型——进行中状态本身不需要携带结果,天然应该兼容所有Task类型的状态要求:
sealed class TaskResult { object NoResult : TaskResult() data class TaskBResult(val resultData: String) : TaskResult() } sealed class TaskStatus<out R : TaskResult> { // 用协变+Nothing表示InProgress不携带结果,可兼容所有R子类型 object InProgress : TaskStatus<Nothing>() data class Completed<R : TaskResult>(val result: R) : TaskStatus<R>() } sealed class Task<R : TaskResult> { abstract val status: TaskStatus<R> data class A( val data: String, override val status: TaskStatus<NoResult>, ) : Task<NoResult>() data class B( val data: String, override val status: TaskStatus<TaskBResult>, ) : Task<TaskBResult>() }
调整的核心设计逻辑:
- 给
TaskStatus的泛型加out协变声明,允许子类型泛型向上兼容 - 用Kotlin内置的
Nothing类型作为InProgress的泛型参数,Nothing是所有类型的子类型,因此TaskStatus.InProgress可以兼容任意TaskStatus<R : TaskResult>的类型要求 - 进行中状态本身不携带结果,用
Nothing刚好符合语义:该状态下永远不会返回结果数据 - 原有的类型约束完全保留:
Task.A完成时只能传NoResult,Task.B完成时只能传TaskBResult,传错类型依然会触发编译错误
测试验证
调整后原测试代码可直接正常编译运行:
fun main() { val taskA = Task.A( data = "data", status = TaskStatus.InProgress ).copy( status = TaskStatus.Completed( result = TaskResult.NoResult ) ) val taskB = Task.B( data = "data", status = TaskStatus.InProgress ).copy( status = TaskStatus.Completed( result = TaskResult.TaskBResult( resultData = "resultData" ) ) ) println(taskA) println(taskB) }
内容的提问来源于stack exchange,提问作者Jan-Willem van Velzen
相关产品推荐
相关产品推荐

