问题描述
在Scala中:
object Strange extends App {
val x = 42
Console.println(x) // => outputs "42", as expected
}
版本2
Version 2
object Strange extends App {
Console.println(x) // => "0" ?!
val x = 42
}
这也是与相同的问题, class
:
class StrangeClass {
Console.println(x) // => still "0"
val x = 42
}
object TestApp extends App {
new StrangeClass()
}
正常方法的正文中没有这样的问题:
There are no such issue with regular method's body:
def nonStrangeMethod {
Console.println(y) // => fails with "not found: value y", as expected
y = 42
}
如果我们在val声明中添加final,行为会发生巨大变化:
And behavior changes dramatically if we'd add "final" to val declaration:
class StrangeClass {
Console.println(x) // => "42", but at least that's expected
final val x = 42
}
对于记录,以下Java静态(Scala的对象
)对应:
For records, the following Java static (Scala's object
) counterpart:
public class Strange {
static {
System.out.println(x);
}
static int x = 42;
public static void main(String[] args) {}
}
$ b b
无法使用plain&在第3行和Java非静态(Scala的 class
)对应部分:无法引用之前定义的字段的可理解错误:
fails compilation with plain & understandable error "Cannot reference a field before it is defined" on line #3 and Java non-static (Scala's class
) counterpart:
public class Strange {
Strange() {
System.out.println(x);
int x = 42;
}
public static void main(String[] args) {
new Strange();
}
}
显然失败,x无法解析为变量on line#3。
obviously fails with "x cannot be resolved to a variable" on line #3.
推荐答案
这是因为 App
其使用延迟初始化。从 中对应用程式
进行编程
It's because of the App
trait which uses delayed initialization. From Programming in Scala regarding the App
trait:
2.9.0版本也注意到了这一点:
The 2.9.0 release notes this too:
code>不会执行Console.println(x),直到 Strange
b
$ b
So Console.println(x)
is not executed until Strange
is ran where you get this as output:
scala> s.main(Array[String]())
0
code>之后 val x = 42
后输出:
If you add another Console.println(x)
after val x = 42
then it prints out:
scala> s.main(Array[String]())
0
42
编译器知道在当前范围中存在 x
,但它会延迟其评估,直到它被执行,然后打印出 Int
这是 0
。
The compiler knows that x
exists in the current scope but it delays evaluation of it until it is executed and then it prints out the default value for Int
which is 0
.
这篇关于Scala中奇怪的行为在类/对象初始化中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!