考虑以下在实数表达式上实现一元和二元运算的人为示例。
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)
+ 从那里扩展,但这是不允许的:错误:...禁止逐个继承。为了克服这个限制,使用提取器在非叶节点上进行模式匹配上面的错误提示:
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)) => ...
我没有尝试过的一件事是使用嵌套函数重载,这似乎有点矫枉过正......
在与上述类似的场景中,是否有匹配多个案例类的好方法?
注意:在继承中添加额外的方法、类、特征是可以的。