【发布时间】:2017-01-16 13:20:26
【问题描述】:
我有以下 ADT:
sealed trait Event
case class EventA(id: Int) extends Event
case class EventB(id: Int) extends Event
case object EventDontCare extends Event
object Event {
def test(ev: Event) = ev match {
case EventA(x) => x
case EventB(y) => y + 1
case EventDontCare => 0
}
}
val eva = EventA(10)
println(Event.test(eva))
它运行良好,但现在我需要有 2 个单独的类型,1 个使用 Int 作为 id 如上所述,另一个使用 String 作为 id。
我尝试将类型参数添加到事件特征:
sealed trait GEvent[ID]
case class GEventA[ID](id: ID) extends GEvent[ID]
case class GEventB[ID](id: ID) extends GEvent[ID]
object EventInt {
type Event = GEvent[Int]
type EventA = GEventA[Int]
type EventB = GEventB[Int]
case object EventDontCare extends GEvent[Int]
def test(ev: Event) = ev match {
case x: EventA => x.id
case y: EventB => y.id + 1
case EventDontCare => 0
}
}
object EventString {....}
val evi = new EventInt.EventA(10)
val evii = GEventA[Int](10)
val evd = EventInt.EventDontCare
println(EventInt.test(evd))
println(EventInt.test(evi))
println(EventInt.test(evii))
我想问几个问题:
- 是否有更好的方法将类型注入 ADT 的所有成员?我对上述方法不满意。
- 在
test方法的模式匹配中,为什么我不能使用case EventA(x) =>或事件case GEventA[Int](x) =>? 同样,为什么我必须使用new关键字创建evi变量? -
即使我已经涵盖了所有 3 种情况,为什么编译器仍然警告我:
匹配可能并不详尽。它会在以下输入上失败: EventDontCare
但它仍然可以正常运行(为 DontCare 案例打印 10)
【问题讨论】:
标签: scala generics domain-driven-design algebraic-data-types