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

use*_*254 4 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)
  }

}
Run Code Online (Sandbox Code Playgroud)

但行

import Expr.Sum
Run Code Online (Sandbox Code Playgroud)

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

ped*_*rla 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)
  }
}
Run Code Online (Sandbox Code Playgroud)

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

class A(val x:Int) {
  object Print { def print = println(x) }
}
Run Code Online (Sandbox Code Playgroud)

如果可以的话import A.Print,哪个值会受到约束x?现在如果我们这样做:

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

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