考虑以下设计的实施一元&的例子。实数表达式的二元运算。
abstract class DoubleE
case class Negate(x: DoubleE) extends DoubleE
case class Reciprocal(x: DoubleE) extends DoubleE
case class Mult(lhs: DoubleE, rhs: DoubleE) extends DoubleE
case class Div(lhs: DoubleE, rhs: DoubleE) extends DoubleE
...
// a lot more binary operations
现在,我想做类似的事情:
(e: DoubleE) match {
case DoubleEUnary(x) => ... // use x ...
case DoubleEBinary(a, b) => ... // use a and b ...
}
有时我甚至想参考匹配的类型;例如
e match {
case DoubeEBinary(a, b) => DoubleEBinary(b, a)
...
}
我尝试过的一些失败的尝试:
abstract case class DoubleEBinary(a: DoubleE, b: DoubleE)
+从中扩展,但不允许这样做:错误: ...禁止使用case-to-case继承。要克服此限制,请使用提取器在非叶节点上进行模式匹配 上述错误暗示:
abstract case class DoubleEBinary(a: DoubleE, b: DoubleE)
def unapply(binOp: DoubleEBinary) = Some((a, b))
哪个不起作用:错误:找不到:值DoubleEBinary
case binOp @ (Mult(a, b) | Div(a, b) | ...) => ...
case binOp(a, b) @ (Mult(_, _) | Div(_, _) | ...) => ...
case (binOp @ Mult(a, b)) | (binOp @ Div(a, b)) => ...
我没有尝试过的一件事就是使用嵌套函数进行重载,这看起来像是一种矫枉过正......
在与上述类似的场景中,是否有一种匹配多个案例类的好方法?
注意:在继承中添加其他方法,类和特征是可以的。
答案 0 :(得分:2)
错误消息中的提示是:
scala> object Binary { def unapply(e: Mult) = Mult.unapply(e) ; def unapply(e: Div) = Div.unapply(e) }
defined object Binary
scala> Div(null,null) match { case Binary(a,b) => (a,b) }
res3: (DoubleE, DoubleE) = (null,null)
抱歉,即将在这里睡觉,最好用unapply(b: Binary)
或DoubleE.unapply(d: DoubleE)
来表示匹配的子类型。
答案 1 :(得分:0)
从 Scala 2.13 开始,可能很早之前,您可以完全按照您输入的内容进行操作