是否可以组成两个密封的类?
Is it possible to compose two sealed classes?
我有两个不同的 Kotlin 密封图像 类。
sealed class Fruit {
object Apple : Fruit()
object Orange : Fruit()
object Banana : Fruit()
}
sealed class Vegetables {
object Broccoli : Vegetable()
object Carrot : Vegetable()
object Spinach : Vegetable()
}
是否可以定义一个包含水果和蔬菜的类型?类似于 Produce = Fruit | Vegetable
这样你就可以写出类似
的东西
fun lookAtProduce(produce: Produce) {
when (produce) {
is Carrot -> {
return "Orange"
}
is Apple -> {
return "Red"
}
....
}
}
fun putItInSalad(vegetable: Vegetable) {
when (vegetable) {
is Spinach -> {
return true
}
is Carrot -> {
return false
}
.....
}
}
创建一个超级class:
sealed class Produce
sealed class Fruit : Produce()
sealed class Vegetable : Produce()
我想你问的是 union type. There have been long discussions 关于向 Kotlin 添加一个,但它看起来不太可能很快发生。
同时,您当然可以有明确的父级 class:
sealed class Produce
接下来的工作与您预期的差不多:
sealed class Fruit : Produce() {
object Apple : Fruit()
object Orange : Fruit()
object Banana : Fruit()
}
sealed class Vegetable : Produce() {
object Broccoli : Vegetable()
object Carrot : Vegetable()
object Spinach : Vegetable()
}
fun lookAtProduce(produce: Produce) =
when (produce) {
is Vegetable.Carrot -> "Orange"
is Fruit.Apple -> "Red"
else -> TODO()
}
}
fun putItInSalad(vegetable: Vegetable) =
when (vegetable) {
is Vegetable.Spinach -> true
is Vegetable.Carrot -> false
else -> TODO()
}
}
(你必须限定 Carrot
等,除非你为它们添加静态导入。)
(TODO()
的好处在于它既可以作为文档,也可以作为一种获取不完整代码进行编译的方法!)
当然,这要求您可以访问要组合的两种类型,因此您可以添加公共父级 class。如果你不能这样做,一个更冗长的选择是使用 Either
class(参见 here)。这将需要明确包装和打开产品,但在这种情况下可能是您可以获得的最接近的产品。
您无法创建联合类型,但您始终可以使用其他密封类型来模拟它。
sealed class Produce {
class FruitProduce(val fruit: Fruit): Produce()
class VegetableProduce(val vegetable: Vegetable): Produce()
}
...然后写
fun color(produce: Produce): String {
return when (produce) {
is Fruit -> when (produce.fruit) {
is Orange -> "Orange"
...
}
is Vegetable -> when (produce.vegetable) {
is Broccoli -> "Green"
...
}
}
}
今天没有比这更好的了:您需要将 fruit
和 vegetable
对象包装在 FruitProduce
和 VegetableProduce
.
中
我有两个不同的 Kotlin 密封图像 类。
sealed class Fruit {
object Apple : Fruit()
object Orange : Fruit()
object Banana : Fruit()
}
sealed class Vegetables {
object Broccoli : Vegetable()
object Carrot : Vegetable()
object Spinach : Vegetable()
}
是否可以定义一个包含水果和蔬菜的类型?类似于 Produce = Fruit | Vegetable
这样你就可以写出类似
的东西fun lookAtProduce(produce: Produce) {
when (produce) {
is Carrot -> {
return "Orange"
}
is Apple -> {
return "Red"
}
....
}
}
fun putItInSalad(vegetable: Vegetable) {
when (vegetable) {
is Spinach -> {
return true
}
is Carrot -> {
return false
}
.....
}
}
创建一个超级class:
sealed class Produce
sealed class Fruit : Produce()
sealed class Vegetable : Produce()
我想你问的是 union type. There have been long discussions 关于向 Kotlin 添加一个,但它看起来不太可能很快发生。
同时,您当然可以有明确的父级 class:
sealed class Produce
接下来的工作与您预期的差不多:
sealed class Fruit : Produce() {
object Apple : Fruit()
object Orange : Fruit()
object Banana : Fruit()
}
sealed class Vegetable : Produce() {
object Broccoli : Vegetable()
object Carrot : Vegetable()
object Spinach : Vegetable()
}
fun lookAtProduce(produce: Produce) =
when (produce) {
is Vegetable.Carrot -> "Orange"
is Fruit.Apple -> "Red"
else -> TODO()
}
}
fun putItInSalad(vegetable: Vegetable) =
when (vegetable) {
is Vegetable.Spinach -> true
is Vegetable.Carrot -> false
else -> TODO()
}
}
(你必须限定 Carrot
等,除非你为它们添加静态导入。)
(TODO()
的好处在于它既可以作为文档,也可以作为一种获取不完整代码进行编译的方法!)
当然,这要求您可以访问要组合的两种类型,因此您可以添加公共父级 class。如果你不能这样做,一个更冗长的选择是使用 Either
class(参见 here)。这将需要明确包装和打开产品,但在这种情况下可能是您可以获得的最接近的产品。
您无法创建联合类型,但您始终可以使用其他密封类型来模拟它。
sealed class Produce {
class FruitProduce(val fruit: Fruit): Produce()
class VegetableProduce(val vegetable: Vegetable): Produce()
}
...然后写
fun color(produce: Produce): String {
return when (produce) {
is Fruit -> when (produce.fruit) {
is Orange -> "Orange"
...
}
is Vegetable -> when (produce.vegetable) {
is Broccoli -> "Green"
...
}
}
}
今天没有比这更好的了:您需要将 fruit
和 vegetable
对象包装在 FruitProduce
和 VegetableProduce
.