无法在抽象类中导入案例类

时间:2012-11-10 01:30:44

标签: scala

我想在下面运行Expr类。我从http://andymaleh.blogspot.ie/2008/04/scalas-pattern-matching-visitor-pattern.html

获取了此代码

以下是我的尝试:

import Expr.Sum

object Main {

    def main(args:Array[String]) {

      var expr1 = new Sum(new Num(1), new Prod(new Num(2), new Num(3)))
      print(expr1)
  }

}

abstract class Expr {

  case class Num(n: Int) extends Expr
  case class Sum(l: Expr , r: Expr) extends Expr
  case class Prod(l: Expr, r: Expr) extends Expr

  def evalExpr(e: Expr): Int = e match {
    case Num(n) => n
    case Sum(l, r) => evalExpr(l) + evalExpr(r)
    case Prod(l, r) => evalExpr(l) * evalExpr(r)
  }

  def printExpr(e: Expr) : Unit = e match {
    case Num(n) => print(" " + n + " ")
    case Sum(l, r) => printExpr(l); print("+"); printExpr(r)
    case Prod(l, r) => printExpr(l); print("x"); printExpr(r)
  }

}

但行

import Expr.Sum

导致编译时错误:'not found:object Expr'。如何导入Expr类?

2 个答案:

答案 0 :(得分:8)

您只能导入实例成员。所以你的代码是:

object Main {
    def main(args:Array[String]) {
      val expr = new Expr {} // now we have a instance.

      import expr._
      var expr1 = new Sum(new Num(1), new Prod(new Num(2), new Num(3)))
      print(expr1)
  }
}

一个简单的例子解释了为什么你不能导入非实例成员:

class A(val x:Int) {
  object Print { def print = println(x) }
}

如果可以import A.Print,哪个值会绑定到x?现在,如果我们这样做:

val a = new A(5); // we have a value bound to x.
import a._
Print.print

这是一个原因。 new A(5).Print != new A(5).Print的另一个原因,不仅在于相等,而且在类型:val (a1, a2) = (new A(5), new A(5)); implicitly[a1.Print <:< a2.Print]中也不会编译。这就是Scala所谓的路径依赖类型

答案 1 :(得分:1)

将案例类移出抽象类会使其编译。在这种情况下,它们也处于相同的范围内,因此无需导入任何内容。

另请注意,import错误在此处不适用,因为MainExpr在同一个程序包中定义。即默认包。

object Main {    
    def main(args:Array[String]) {

      var expr1 = new Sum(new Num(1), new Prod(new Num(2), new Num(3)))
      print(expr1)
  }
}

abstract class Expr {
}

case class Num(n: Int) extends Expr
case class Sum(l: Expr , r: Expr) extends Expr
case class Prod(l: Expr, r: Expr) extends Expr

def evalExpr(e: Expr): Int = e match {
  case Num(n) => n
  case Sum(l, r) => evalExpr(l) + evalExpr(r)
  case Prod(l, r) => evalExpr(l) * evalExpr(r)
}

def printExpr(e: Expr) : Unit = e match {
  case Num(n) => print(" " + n + " ")
  case Sum(l, r) => printExpr(l); print("+"); printExpr(r)
  case Prod(l, r) => printExpr(l); print("x"); printExpr(r)
}

运行此命令:

scala>Main.main(Array[String]())
Sum(Num(1),Prod(Num(2),Num(3)))