gpt4 book ai didi

scala - 加载扩展 App 的对象时,Scala 会发生什么?

转载 作者:行者123 更新时间:2023-12-04 17:37:45 30 4
gpt4 key购买 nike

我在扩展 App 的对象中遇到了一些奇怪的行为。 .看看下面的 REPL 命令:

scala> object A extends App {val x = "I am null"}
defined module A

scala> object B {val x = "I am a string"}
defined module B

scala> A.x
res0: java.lang.String = null

scala> B.x
res1: java.lang.String = I am a string

嗯,这有点奇怪……但它变得更奇怪了。然后我想到了 object 中的 vals进行一些懒惰的评估...所以我尝试了一个真正的 lazy val :
scala> object C extends App {lazy val x = "What am I?"}
defined module C

scala> C.x
res2: java.lang.String = What am I?

那么这里发生了什么?为什么常规 val 获得空值?
为什么当我使用 lazy val 时这种行为会改变? App 有什么特别之处?特质,这使得常规 vals 未被评估?

最佳答案

应用程序扩展 DelayedInit特征。因此所有语句和所有值定义都移至 delayedInit方法。 Lazy val 有效,因为它编译为方法。

例如,如果你反编译这个类:

class TestApp extends App{
val test = "I am null"
lazy val testLazy ="I am a string"
}

您将获得带有“懒惰方法”的类(class):
public String testLazy()
{
if((bitmap$0 & 1) == 0)
synchronized(this)
{
if((bitmap$0 & 1) == 0)
{
testLazy = "I am a string";
bitmap$0 = bitmap$0 | 1;
}
BoxedUnit _tmp = BoxedUnit.UNIT;
}
return testLazy;
}

和内部类中的延迟初始化方法 delayedInit.body :
 public final class delayedInit.body extends AbstractFunction0
implements ScalaObject
{

public final Object apply()
{
$outer.test_$eq("I am null");
return BoxedUnit.UNIT;
}

private final TestApp $outer;
....

所以值“我是空的”将被分配给 test字段仅在调用 delayInit 时。

关于scala - 加载扩展 App 的对象时,Scala 会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13009265/

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