可能重复:
Scala 和前向引用
为什么以下在 Scala 中有效:
版本 1
object Strange extends App {
val x = 42
Console.println(x) // => outputs "42", as expected
}
版本 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()
}
常规方法的主体没有这样的问题:
def nonStrangeMethod {
Console.println(y) // => fails with "not found: value y", as expected
y = 42
}
如果我们将“final”添加到 val 声明中,行为会发生巨大变化:
class StrangeClass {
Console.println(x) // => "42", but at least that's expected
final val x = 42
}
作为记录,以下 Java 静态(Scala 的object
)对应物:
public class Strange {
static {
System.out.println(x);
}
static int x = 42;
public static void main(String[] args) {}
}
class
在第 3 行和 Java 非静态(Scala's )对应项上出现简单且可理解的错误“无法在定义之前引用字段”的编译失败:
public class Strange {
Strange() {
System.out.println(x);
int x = 42;
}
public static void main(String[] args) {
new Strange();
}
}
显然在第 3 行出现“x 无法解析为变量”而失败。