我在扩展 App
的对象中遇到了一些bizzar行为 . 看看以下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
特性有什么特别之处,这使得常规值不被评估?
1 回答
App扩展DelayedInit特质 . 因此,所有语句和所有值定义都移动到
delayedInit
方法 . Lazy val可以工作,因为它编译为方法 .例如,如果您反编译此类:
您将使用'懒惰方法'获得课程:
和内部类中的delayedInit方法
delayedInit.body
:因此,只有在调用delayedInit时,才会将"I am null"赋值给
test
字段 .