覆盖'val'时出现意外结果

时间:2015-03-27 17:46:18

标签: scala override

在Scala 2.10.4中,给出以下类:

scala> class Foo { 
     |   val x = true
     |   val f = if (x) 100 else 200
     | }
defined class Foo

以下两个例子对我有意义:

scala> new Foo {}.f
 res0: Int = 100

scala> new Foo { override val x = false}.f
res1: Int = 200

但是,为什么此次通话不会返回100

scala> new Foo { override val x = true }.f
res2: Int = 200

1 个答案:

答案 0 :(得分:11)

由于vals未经多次初始化,x在初始化{{1}期间实际上是null(或false为默认Boolean然后在您的示例中扩展Foo的匿名类中初始化。

我们可以使用Foo

更轻松地对其进行测试
AnyRef

Scala FAQ中有完整的解释。摘录:

  

当val被覆盖时,它不会被初始化多次。因此,虽然上面示例中的x2似乎在每个点上定义,但情况并非如此:在构造超类时,重写的val似乎为null,而抽象的val也是如此。

避免这种情况的一种简单方法是使用惰性val或def,如果被引用的val可能被覆盖。

此外,您可以使用class Foo { val x = "" val f = if (x == null) "x is null" else "not null" } scala> new Foo { override val x = "a" }.f res10: String = x is null scala> new Foo {}.f res11: String = not null 编译器标志来警告您可能出现的初始化错误。