Scala中类之间的循环引用

时间:2015-08-27 21:16:02

标签: scala

以下是代码:

  trait Simplifier {
    def caseNum(t: Num) = {
      t.value
    }
    def caseMul(t: Mul) = {
      t.right.simplify(this) * t.left.simplify(this)
    }
    def caseVar(t: Var) = {
      t.assigned.simplify(this)
    }
  }

  trait Expr {
    def simplify(s: Simplifier): Int
  }

  class Num(val value: Int) extends Expr {
    def simplify(s: Simplifier) = {
      s.caseNum(this)
    }
  }

  class Var(val assigned: Expr) extends Expr {
    def simplify(s: Simplifier) = {
      s.caseVar(this)
    }
  }

  class Mul(val left: Expr, val right: Expr) extends Expr {
    def simplify(s: Simplifier) = {
      s.caseMul(this)
    }
  }

如果将其粘贴到repl中,您将获得

<console>:11: error: not found: type Num
           def caseNum(t: Num) = {
                          ^
<console>:14: error: not found: type Mul
           def caseMul(t: Mul) = {
                          ^
<console>:17: error: not found: type Var
           def caseVar(t: Var) = {
                          ^

如果更改定义的顺序,您仍会遇到类似的错误。

2 个答案:

答案 0 :(得分:3)

如果您在REPL使用:paste,则编译正常。如果没有:paste命令,评估将立即进行,尚未定义尚未定义的类,因此失败。在粘贴模式下,它们被编译在一起。

见下文:

scala> :paste
// Entering paste mode (ctrl-D to finish)

 trait Simplifier {
    def caseNum(t: Num) = {
      t.value
    }
    def caseMul(t: Mul) = {
      t.right.simplify(this) * t.left.simplify(this)
    }
    def caseVar(t: Var) = {
      t.assigned.simplify(this)
    }
  }

  trait Expr {
    def simplify(s: Simplifier): Int
  }

  class Num(val value: Int) extends Expr {
    def simplify(s: Simplifier) = {
      s.caseNum(this)
    }
  }

  class Var(val assigned: Expr) extends Expr {
    def simplify(s: Simplifier) = {
      s.caseVar(this)
    }
  }

  class Mul(val left: Expr, val right: Expr) extends Expr {
    def simplify(s: Simplifier) = {
      s.caseMul(this)
    }
  }

// Exiting paste mode, now interpreting.

defined trait Simplifier
defined trait Expr
defined class Num
defined class Var
defined class Mul

答案 1 :(得分:1)

使用:paste命令的替代方法是手动将代码包装在包装器对象中。

scala> object Wrapper {
     |   trait Simplifier {
     |     def caseNum(t: Num) = {
     |       t.value
     |     }
     |     def caseMul(t: Mul) = {
     |       t.right.simplify(this) * t.left.simplify(this)
     |     }
     |     def caseVar(t: Var) = {
     |       t.assigned.simplify(this)
     |     }
     |   }
     | 
     |   trait Expr {
     |     def simplify(s: Simplifier): Int
     |   }
     | 
     |   class Num(val value: Int) extends Expr {
     |     def simplify(s: Simplifier) = {
     |       s.caseNum(this)
     |     }
     |   }
     | 
     |   class Var(val assigned: Expr) extends Expr {
     |     def simplify(s: Simplifier) = {
     |       s.caseVar(this)
     |     }
     |   }
     | 
     |   class Mul(val left: Expr, val right: Expr) extends Expr {
     |     def simplify(s: Simplifier) = {
     |       s.caseMul(this)
     |     }
     |   }
     | }
defined module Wrapper

scala> import Wrapper._
import Wrapper._