这在目前的语言中似乎是不可能的。但是,我们可以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
在密封层次结构中)。
参考: