我试图了解范围内的范围是如何工作的。我试着深入了解Joshua Suereth的书Scala的第5.1.1节。这是在Windows XP,Java 7和Scala 2.9.1上。我在REPL中声明了一个类Dinner
。绑定Dinner
存在于本地范围中。然后我实例化,因为它是本地绑定的。
scala> class Dinner {
| val veggie="broccoli"
| def announceDinner(veggie: String){
| println("Dinner happens to be tasteless " + veggie + " soup")
| }
| }
defined class Dinner
scala> new Dinner
res1: Dinner = Dinner@27fb77
到目前为止一切顺利。名称Dinner
已在本地绑定,我们还可以构建一个val x
来保存对new Dinner
的引用。
据我所知,到目前为止,REPL将在内部将上述代码包装在对象中。好吧,我对Scala的了解还不是很深入,我试图理解Class如何被REPL内部包装。
是否有可以帮助我评估这些对象的REPL命令?
答案 0 :(得分:3)
这里有一个非常快速和肮脏的方式来处理REPL中发生的事情。
使用scala -Xprint:typer
调用REPLscala> class Dinner {
| val veggie="broccoli"
| def announceDinner(veggie: String){
| println("Dinner happens to be tasteless " + veggie + " soup")
| }
| }
[[syntax trees at end of typer]]// Scala source: <console>
package $line1 {
final object $read extends java.lang.Object with ScalaObject {
def this(): object $line1.$read = {
$read.super.this();
()
};
final object $iw extends java.lang.Object with ScalaObject {
def this(): object $line1.$read.$iw = {
$iw.super.this();
()
};
final object $iw extends java.lang.Object with ScalaObject {
def this(): object $line1.$read.$iw.$iw = {
$iw.super.this();
()
};
class Dinner extends java.lang.Object with ScalaObject {
def this(): $line1.$read.$iw.$iw.Dinner = {
Dinner.super.this();
()
};
private[this] val veggie: java.lang.String = "broccoli";
<stable> <accessor> def veggie: java.lang.String = Dinner.this.veggie;
def announceDinner(veggie: String): Unit = scala.this.Predef.println("Dinner happens to be tasteless ".+(veggie).+(" soup"))
}
}
}
}
}
[[syntax trees at end of typer]]// Scala source: <console>
package $line1 {
final object $eval extends java.lang.Object with ScalaObject {
def this(): object $line1.$eval = {
$eval.super.this();
()
};
private[this] val $print: String = {
$read.$iw.$iw;
"defined class Dinner\012"
};
<stable> <accessor> def $print: String = $eval.this.$print
}
}
defined class Dinner
您可以检查上方Dinner
最终包含在$line1.$read.$iw.$iw
中。现在让我们看看接下来会发生什么:
[[syntax trees at end of typer]]// Scala source: <console>
package $line2 {
final object $read extends java.lang.Object with ScalaObject {
def this(): object $line2.$read = {
$read.super.this();
()
};
final object $iw extends java.lang.Object with ScalaObject {
def this(): object $line2.$read.$iw = {
$iw.super.this();
()
};
import $line1.$read.$iw.$iw.Dinner;
final object $iw extends java.lang.Object with ScalaObject {
def this(): object $line2.$read.$iw.$iw = {
$iw.super.this();
()
};
private[this] val res0: $line1.$read.$iw.$iw.Dinner = new $line1.$read.$iw.$iw.Dinner();
<stable> <accessor> def res0: $line1.$read.$iw.$iw.Dinner = $iw.this.res0
}
}
}
}
[[syntax trees at end of typer]]// Scala source: <console>
package $line2 {
final object $eval extends java.lang.Object with ScalaObject {
def this(): object $line2.$eval = {
$eval.super.this();
()
};
lazy private[this] var $result: $line1.$read.$iw.$iw.Dinner = {
$eval.this.$print;
$line2.$read.$iw.$iw.res0
};
private[this] val $print: String = {
$read.$iw.$iw;
"res0: $line1.$read.$iw.$iw.Dinner = ".+(scala.runtime.ScalaRunTime.replStringOf($line2.$read.$iw.$iw.res0, 1000))
};
<stable> <accessor> def $print: String = $eval.this.$print
}
}
与以前基本相同,但使用$line2
代替$line1
。请注意import $line1.$read.$iw.$iw.Dinner
之前的$line2.$read.$iw.$iw
。
通过这种方式,我们可以看到为什么在两个不同的行中定义伴随对象不起作用,它们最终被包装到不同的对象中,并且需要在同一范围/源文件中定义伴随。