Kotlin and discriminated unions (sum types)

后端 未结 3 1120
慢半拍i
慢半拍i 2021-02-03 17:36

Does Kotlin have anything like discriminated unions (sum types)? What would be the idiomatic Kotlin translation of this (F#):

type OrderMessage =
    | New of Id         


        
3条回答
  •  伪装坚强ぢ
    2021-02-03 18:09

    The common way of implementing this kind of abstraction in an OO-language (e.g. Kotlin or Scala) would be to through inheritance:

    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()
    }
    

    You can push the common part to the superclass, if you like:

    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)
    }
    

    The type checker doesn't know that such a hierarchy is closed, so when you do a case-like match (when-expression) on it, it will complain that it is not exhaustive, but this will be fixed soon.

    Update: while Kotlin does not support pattern matching, you can use when-expressions as smart casts to get almost the same behavior:

    when (message) {
      is New -> println("new $id: $quantity")
      is Cancel -> println("cancel $id")
    }
    

    See more about smart casts here.

提交回复
热议问题