2011-07-29 69 views
10

我可能在这里有一个愚蠢的问题......我似乎无法弄清楚如何在Scala中创建不带参数的构造函数。我知道我可以把所有的东西写在课堂上(特别是因为它是我需要的唯一构造函数),但是它不太合适。没有参数的斯卡拉构造函数

我有什么:

class Foo { 
     //some init code 

     //... 
    } 

我想什么(但因为它要我调用另一个构造第一不工作):

class Foo { 
     // The only constructor 
     def this() = { 
      //some init code 
     } 

     //... 
    } 

回答

16

Scala中的类都具有主构造函数和可选的一些辅助构造函数(它们必须遵从主构造函数或其他辅助构造函数)。

你的情况的问题是,在这两种情况下,你已经定义主构造函数为不带参数 - 然后在第二种情况下,你尝试定义一个具有相同签名的辅助构造函数。这不起作用,出于同样的原因,以下不会编译:

// Primary constructor takes a String 
class Foo(s: String) { 
    // Auxiliary constructor also takes a String?? (compile error) 
    def this(a: String) { 
     this(a) 
    } 
} 

这不是什么关系的事实,构造器是无参数;例如下面的编译:

class Foo(s: String) { 
    // alternative no-arg constructor (with different signature from primary) 
    def this() { 
     this("Default value from auxiliary constructor") 
    } 
} 

特别是,在你的第二个例子,您的评论“唯一的构造函数”是错误。辅助构造函数是总是次要主构造函数,并且永远不可能是唯一的构造函数。

FWIW,第一个例子是唯一对您开放的选项,但它对我来说看起来很好。如果你刚开始使用Scala,我相信它很快就会开始感觉良好 - 当有更多的惯用选择时,避免Java风格的做事方式是很重要的。

+2

辅助构造函数也可以服从前面定义的其他辅助构造函数。 –

+0

@ jean-phillipe:谢谢,你说得对。我刚刚意识到这在我自己的广泛范围内并不准确;现在更正后。 –

+0

谢谢,从一开始就让我对Scala构造函数感到困扰,但它从来没有像我这么做太多......现在已经很清楚了。 – HairyFotr

4

把init代码放在类的主体中是构造函数不带参数的唯一方法。我想如果你想你可以做这样的事情:

class Foo { 

    private def init { 
    //init code here 
    } 

    init() 
} 

这就像你会得到。

10

对于什么值得你可以引入一个额外的范围来“标记”init代码。

class Foo { 
    { 
     // init code here 
    } 
} 
+0

我非常喜欢这个。来自Java,在类体中使用默认的构造函数代码只是感觉太乱了! –

+0

Thx对于好的话,但如果我是你,我不会习惯它。过去7年来我一直在Scala风景中,甚至没有见过这种模式在任何地方使用过,甚至一次。 ;) – agilesteel

4

初始化代码的方法的主体。但是你可以这样做,如果它困扰你的话:

class Foo { 
     locally { 
      //some init code 
     } 
} 
+0

在这种情况下,“本地”是什么?这是一个保留字吗?它可以在任何地方引用吗? –

+0

@user它是在'Predef'上定义的内联方法,它返回块的值。它可以在任何地方被引用。 –