Kotlin有没有像歧视的工会(总和类型)?什么是惯用的Kotlin翻译(F#):
type OrderMessage =
| New of Id: int * Quantity: int
| Cancel of Id: int
let handleMessage msg =
match msg with
| New(id, qty) -> handleNew id qty
| Cancel(id) -> handleCxl id
答案 0 :(得分:29)
在OO语言(例如Kotlin或Scala)中实现这种抽象的常用方法是通过继承:
open class OrderMessage private () { // private constructor to prevent creating more subclasses outside
class New(val id: Int, val quantity: Int) : OrderMessage()
class Cancel(val id: Int) : OrderMessage()
}
如果您愿意,可以将公共部分推送到超类:
open class OrderMessage private (val id: Int) { // private constructor to prevent creating more subclasses outside
class New(id: Int, val quantity: Int) : OrderMessage(id)
class Cancel(id: Int) : OrderMessage(id)
}
类型检查器不知道这样的层次结构是关闭的,所以当你对它进行类似案例的匹配(when
- 表达式)时,它会抱怨它并非详尽无遗,而是这将很快修复。
更新:虽然Kotlin不支持模式匹配,但您可以使用 - 表达式作为智能广播来获得几乎相同的行为:
when (message) {
is New -> println("new $id: $quantity")
is Cancel -> println("cancel $id")
}
详细了解智能广告here。
答案 1 :(得分:29)
Kotlin's sealed class
解决该问题的方法与Scala sealed class
and sealed trait
非常相似。
示例(摘自链接的Kotlin文章):
sealed class Expr {
class Const(val number: Double) : Expr()
class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
}
答案 2 :(得分:3)
Kotlin中的密封类被设计为能够表示求和类型,因为它与Scala中的密封特征一起发生。
示例:
sealed class OrderStatus {
object Approved: OrderStatus()
class Rejected(val reason: String): OrderStatus()
}
当在比赛的when表达式中使用密封类时,使用密封类的主要好处就发挥了作用。
如果可以验证该语句是否涵盖所有情况,则无需在该语句中添加else子句。
private fun getOrderNotification(orderStatus:OrderStatus): String{
return when(orderStatus) {
is OrderStatus.Approved -> "The order has been approved"
is OrderStatus.Rejected -> "The order has been rejected. Reason:" + orderStatus.reason
}
}
有几件事要记住:
在Kotlin中执行智能广播时,这意味着在此示例中无需执行从OrderStatus到OrderStatus的转换。拒绝访问原因属性。
如果我们没有定义拒绝案例的处理方法,则编译将失败,并且在IDE中会出现如下警告:
“何时”表达式必须详尽无遗,请添加必要的“ is Rejected”分支或“ else”分支。
这是我博客的链接(西班牙语),在该博客上,我有一篇更完整的有关ADT的文章,其中包含kotlin示例:http://xurxodev.com/tipos-de-datos-algebraicos/