4

我找不到这个简单问题的答案,也许我使用了错误的关键字进行搜索。

要创建 AST,我需要 Number、Add、Sub、Mul、Div 等节点。由于许多数学运算具有相同的结构,我如何在相同的模式匹配情况下处理它们?例如,据说下面的行在语法上是不正确的:

object AST {
  sealed abstract class Expr
  case class MathOp(e1: Expr, e2: Expr) extends Expr
  case class Number extends Expr

  case class Add(e1: Expr, e2: Expr) extends MathOp(e1, e2)
  case class Sub(e1: Expr, e2: Expr) extends MathOp(e1, e2)
}

目的是能够做到:

expr match {
  case MathOp(e1: Expr, e2: Expr) => //do something that would be done to Add, Sub, Mul, Div
  case Number => //do another thing
}
4

2 回答 2

5

case 类的作用远不止添加模式匹配提取器,例如它们添加相等、乘积迭代器和 arity 等,因此在继承下会发生奇怪的事情。因此,案例类继承以前被弃用,现在在 Scala 2.10 中是不可能的。

对于您的情况,您需要一个自定义提取器(unapply方法):

object AST {
  sealed trait Expr
  object MathOp {
    def unapply(m: MathOp): Option[(Expr, Expr)] = Some(m.e1 -> m.e2)
  }
  sealed trait MathOp extends Expr {
    def e1: Expr
    def e2: Expr
  }
  case class Number extends Expr

  case class Add(e1: Expr, e2: Expr) extends MathOp
  case class Sub(e1: Expr, e2: Expr) extends MathOp
}

相关问题

于 2013-06-19T22:42:20.433 回答
0

据我所知,我没有理由为孩子们使用“案例课程”。希望正确的代码如下:

object AST {
  sealed abstract class Expr
  case class MathOp(e1: Expr, e2: Expr) extends Expr
  case class Number extends Expr

  class Add(e1: Expr, e2: Expr) extends MathOp(e1, e2)
  class Sub(e1: Expr, e2: Expr) extends MathOp(e1, e2)
}

expr match {
  case MathOp(e1: Expr, e2: Expr) => //do something that would be done to Add, Sub, Mul, Div
  case Number => //do another thing
}
于 2013-06-19T09:39:02.187 回答