这在目前的语言中似乎是不可能的。
但是,我们可以将 NO_OP 从密封层次结构中移出,并使用箭头库中的 Coproduct 来定义临时密封层次结构:
import arrow.generic.coproduct2.Coproduct2
sealed class Operation {
class Add(val value: Int) : Operation()
class Substract(val value: Int) : Operation()
class Multiply(val value: Int) : Operation()
class Divide(val value: Int) : Operation()
}
object NO_OP
typealias Operations = Coproduct2<NO_OP, Operation>
或者我们可以修复Coproduct中的类型参数之一,并且有:
typealias SomeThingWithNoOp<T> = Coproduct<NO_OP, T>
但是,这并不理想,因为它使层次结构嵌套。顶层是Coproduct,嵌套层是自定义层次结构。
这可能会在不久的将来通过 Arrow-Meta 的联合类型插件来解决。
查看问题的另一种方法是将NO_OP 视为标记值。因此我们可以将NO_OP 编码为null 或None(来自箭头选项):
sealed class Operation {
class Add(val value: Int) : Operation()
class Substract(val value: Int) : Operation()
class Multiply(val value: Int) : Operation()
class Divide(val value: Int) : Operation()
}
typealias Operations = Operation?
import arrow.core.Option
sealed class Operation {
class Add(val value: Int) : Operation()
class Substract(val value: Int) : Operation()
class Multiply(val value: Int) : Operation()
class Divide(val value: Int) : Operation()
}
typealias Operations = Option<Operation>
根据我的经验,将其编码为可空可能更容易使用,因为 Kotlin 具有内置的可空类型支持。虽然将其编码为Option、Coproduct 或在每个密封层次结构中定义NO_OP 会使其更加明显(尤其是通过在密封层次结构中使用Coproduct 或NO_OP)。
参考: