[英]How do I write Nested Generics in Kotlin's Sealed Classes
我正在尝试提供一个数据 model,它允许我执行以下操作:
Task
类型并更改其Status
Status
可以是进行InProgress
或Completed
Status
的情况下,我希望能够添加特定于已完成Task
的数据。最初,我想出了这个数据 model:
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>()
}
sealed class TaskStatus<R : TaskResult> {
object InProgress : TaskStatus<NoResult>()
data class Completed<R : TaskResult>(val result: R) : TaskStatus<R>()
}
sealed class TaskResult {
object NoResult : TaskResult()
data class TaskBResult(val resultData: String) : TaskResult()
}
这里有Task.A
和Task.B
,其中:
Task.A
只接受NoResult
Task.B
只接受TaskBResult
但是,当我运行它时:
fun main() {
val taskA = Task.A(
data = "data",
status = TaskStatus.InProgress
).copy(
status = TaskStatus.Completed(
result = NoResult
)
)
val taskB = Task.B(
data = "data",
status = TaskStatus.InProgress
).copy(
status = TaskStatus.Completed(
result = TaskBResult(
resultData = "resultData"
)
)
)
}
我收到以下用于设置Task.B
初始状态的编译错误:
status = TaskStatus.InProgress
Type mismatch.
Required: TaskStatus<TaskResult.TaskBResult>
Found: TaskStatus.InProgress
有谁知道如何更改数据 model 以便我可以运行此(或非常相似的) main
function?
这可以通过非常小的更改工作:只需将TaskStatus
协变泛型 class 并将InProgress
TaskStatus<Nothing>
。 当您有不代表 state 的“特殊情况”对象时,这是您可以使用的典型策略。此更改后,您的代码应该编译:
sealed class Task<R : TaskResult> {
abstract val status: TaskStatus<R>
data class A(
val data: String,
override val status: TaskStatus<TaskResult.NoResult>,
) : Task<TaskResult.NoResult>()
data class B(
val data: String,
override val status: TaskStatus<TaskResult.TaskBResult>,
) : Task<TaskResult.TaskBResult>()
}
sealed class TaskStatus<out R : TaskResult> {
object InProgress : TaskStatus<Nothing>()
data class Completed<R : TaskResult>(val result: R) : TaskStatus<R>()
}
sealed class TaskResult {
object NoResult : TaskResult()
data class TaskBResult(val resultData: String) : TaskResult()
}
fun main() {
val taskA = Task.A(
data = "data",
status = TaskStatus.InProgress
).copy(
status = TaskStatus.Completed(
result = NoResult
)
)
val taskB = Task.B(
data = "data",
status = TaskStatus.InProgress
).copy(
status = TaskStatus.Completed(
result = TaskBResult(
resultData = "resultData"
)
)
)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.