gpt4 book ai didi

scala - 试图了解在 REPL 上声明的类在内部是如何处理的

转载 作者:行者123 更新时间:2023-12-02 00:19:33 25 4
gpt4 key购买 nike

我正在尝试了解范围界定在 REPL 中的工作原理。我尝试深入了解 Joshua Suereth 的书 Scala 的第 5.1.1 节。这是在 Windows XP、Java 7 和 Scala 2.9.1 上进行的。我在 REPL 中声明了一个类 Dinner。绑定(bind) Dinner 存在于本地范围内。然后我实例化,因为它是本地绑定(bind)的。

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 在本地绑定(bind),我们还可以构造一个 val x 来保存对 new Dinner 的引用。

据我所知,REPL 会在内部将上述代码包装在对象中。好的,我对 Scala 的了解还不是很深,我正在尝试了解 REPL 如何在内部包装类。

是否有 REPL 命令可以帮助我评估这些对象?

最佳答案

这里有一个非常快速和肮脏的方式来了解 REPL 中发生的事情。

使用 scala -Xprint:typer 调用 REPL

scala> 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 之前。

这样我们就可以明白为什么在两行不同的行中定义伴随对象不起作用,它们最终被包装到不同的对象中,并且需要在相同的范围/源文件中定义伴随对象。

关于scala - 试图了解在 REPL 上声明的类在内部是如何处理的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11549174/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com