2011-07-29 68 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'上定義的內聯方法,它返回塊的值。它可以在任何地方被引用。 –