2012-09-02 46 views
3

为什么在下面的代码中会出现空指针异常?特质实例抛出空指针

object Test extends App{ 
    trait MyTrait[A]{ self => 
     val seq: Seq[A] 
     val size = seq.size // null pointer here 
    } 

    val p = new MyTrait[Int]{ 
     val seq = Seq(1,2,3) 
    } 
} 

如果我将大小字段更改为懒惰,那就可以了。

回答

6

字段按照它们混合的顺序进行初始化 - 因此首先发生在特征中的所有内容,然后val被分配给Seq(1,2,3)(因为您基本上以匿名特征混合)。

正如你所发现的,lazy val往往是一条出路这个烂摊子:你实际上并不叫seq.size直到你需要它,这就是你已经填充seq后场。

5

风格建议是为了避免特征中的vals,因为init命令地雷而支持defs和lazy vals。

样品谈话: https://groups.google.com/forum/?fromgroups=#!topic/scala-user/nrOrjPOYmb0

+0

感谢。就像使用def的想法一样,似乎更加整洁。 – Pengin

+1

@Pengin - 我以为你使用'val'来缓存值。例如'List'需要'O(n)'来查找大小 - 它必须遍历列表。在那种情况下,'def'在加速事物方面没有任何用处。 –

+0

@RexKerr - 是的,我把这里给出的简单例子与不同的代码搞混了。 – Pengin