Scala For表达式在伴随对象中声明的集合上抛出NullPointerException

Scala For表达式在伴随对象中声明的集合上抛出NullPointerException,scala,Scala,我有以下代码(简化): case类元素(x:Int,y:Int) 案例类控制器(元素:集合[元素]){ 导入控制器_ def neights(e:Element):Set[Element]=Set.empty[Element]//这仅用于获取要编译的代码 def merge(that:Controller):Controller=Controller(elems++that.elems) 定义:控制器={ { println(s“使用规则$rules进行演变”); 对于(规则集大小set.siz

我有以下代码(简化):

case类元素(x:Int,y:Int)
案例类控制器(元素:集合[元素]){
导入控制器_
def neights(e:Element):Set[Element]=Set.empty[Element]//这仅用于获取要编译的代码
def merge(that:Controller):Controller=Controller(elems++that.elems)
定义:控制器={
{
println(s“使用规则$rules进行演变”);
对于(规则集大小<2
val rule2:Rule=(e:Element,set:set[Element])=>set.size<4&&set.size>1
}
我的问题是
evolve
方法抛出了一个null指针异常。 经过一些调查,我意识到问题在于同伴对象中设置的
规则
,由于某种原因,现在使用的是设置为(null)的println,如println中的
println(s“Evolving using rules$rules”);
所示

有人能解释为什么吗?
如果我在下面几行中添加两个我匿名实现的
规则,为什么设置了规则(null)?
这个问题是否与我有一个case类,并且伴随对象没有像我期望的那样工作有关


感谢您的澄清。

TLDR:这是初始化顺序

您的代码可以缩短为

object Foo { 
    val foo = Set(bar1, bar2)
    val bar1 = "a"
    val bar2 = "b"
}
问题是声明是以自顶向下的方式处理的,所以在初始化foo并设置值时,bar1和bar2还没有赋值,所以调用看起来像

val foo = Set(null, null)
这显然会导致Set(null)

要解决此问题,请将规则1和规则2移到规则之前(或者,将
val
def
交换,或者为规则1/rule2应用
lazy val
,但我怀疑您的情况是否如此)

您可能会争辩说,在java中,您不会遇到同样的问题,但您会——几乎准确的翻译是:

class Foo {
    Set<String> foo;
    String bar1;
    String bar2;

    Foo() {
        foo = new HashSet<String>();
        foo.add(bar1);
        foo.add(bar2);
        bar1 = "a";
        bar2 = "b";
    }
}
class-Foo{
集富;
串杆1;
串杆2;
Foo(){
foo=新的HashSet();
foo.add(bar1);
foo.add(bar2);
bar1=“a”;
bar2=“b”;
}
}
class Foo {
    Set<String> foo;
    String bar1;
    String bar2;

    Foo() {
        foo = new HashSet<String>();
        foo.add(bar1);
        foo.add(bar2);
        bar1 = "a";
        bar2 = "b";
    }
}