1
我有幾個事件類定義和外部由接口描述語言生成。這些類型的定義是超出了我的控制 - 我只獲得了簡單的生成case類:斯卡拉隱式類與異類的子類型列表
sealed trait Event
case class EventOpen(msg: String) extends Event
case class EventClose(msg: String) extends Event
鑑於這些事件的列表,我需要把它們摺疊成一個單一的價值。目的是構建一個摺疊函數庫,可以根據需要爲特定的上下文使用。例如,確定一個流是打開還是關閉。爲了避免摺疊函數中的巨大模式匹配,因爲事件列表相當長,我希望能夠使用隱式類來根據需要爲每個事件添加功能,並根據需要打包它們以導入:
sealed trait Status
case object Open extends Status
case object Closed extends Status
case object Unknown extends Status
// Do nothing unless a specific EventOp is defined.
implicit class EventNoOp(event: Event) {
def accumulate(status: Status): Status = status
}
implicit class EventOpenOp(event: EventOpen) {
def accumulate(status: Status): Status = Open
}
implicit class EventCloseOp(event: EventClose) {
def accumulate(status: Status): Status = Closed
}
val initial: Status = Unknown
List(EventOpen("yeeha"), EventClose("adios")).foldLeft(initial)((status, event) => event.accumulate(status)) // => Unknown
問題是特定類型的事件在摺疊中丟失,所以只有EventNoOp被調用,導致「未知」而不是「已關閉」。明確的模式匹配裏面的摺疊功能解決了這個問題,但失敗的辦法擺在首位的宗旨:
val initial: Status = Unknown
List(EventOpen("yeeha"), EventClose("adios")).foldLeft(initial)((status, event) => {
event match {
case e: EventOpen => e.accumulate(status)
case e: EventClose => e.accumulate(status)
}
})
有什麼辦法,以避免對每一個事件一個明確的模式匹配?