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
この種の抽象化を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
- expression)を実行すると、完全ではないというメッセージが表示されますが、これは修正されますすぐに。
Update:Kotlinはパターンマッチングをサポートしていませんが、when-式をスマートキャストとして使用すると、ほぼ同じ動作が得られます。
when (message) {
is New -> println("new $id: $quantity")
is Cancel -> println("cancel $id")
}
スマートキャストについての詳細 ここ を参照してください。
Kotlinのsealed class
その問題へのアプローチは Scala sealed class
およびsealed trait
。
例(リンクされたKotlinの記事から引用):
sealed class Expr {
class Const(val number: Double) : Expr()
class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
}
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.Rejectedへの変換を実行する必要はありません。
拒否された場合の対処方法を定義していない場合、コンパイルは失敗し、IDEには次のような警告が表示されます。
'when'式は完全でなければならないので、代わりに必要な 'is Rejected'ブランチまたは 'else'ブランチを追加してください。
これは私のブログ(スペイン語)へのリンクです。ここには、ADTに関するKotlinの例を含むより完全な記事があります。 http://xurxodev.com/tipos-de-datos-algebraicos/