2009-07-13 83 views
59

在Scala中,類的主構造函數沒有明確的主體,但是從類主體隱式定義。那麼,如何區分字段和本地值(即構造函數方法的本地值)呢?如何在Scala的主構造函數中定義一個局部var/val?

例如,採取下面的代碼片段,從「在Scala編程」一些示例代碼修改的形式:

class R(n: Int, d: Int) { 
    private val g = myfunc 
    val x = n/g 
    val y = d/g 
} 

我的理解是,這將產生三個字段類:私人「 g「,公共」x「和」y「。但是,g值只用於計算x和y字段,超出構造函數範圍沒有意義。

所以在這個(誠然是人爲的)例子中,你如何去爲這個構造函數定義本地值?

+0

如果別人有類似的問題,像我一樣來到這裏,就像我一樣來到這裏。如果你正在嘗試做同樣的概念,但爲_constructors_使用我的問題的答案:https://stackoverflow.com/questions/46455835/how-to-define-val-inside-class-constructor-in-scala – 2017-09-27 20:25:55

回答

37

E.g.

class R(n: Int, d: Int) { 
    val (x, y) = { 
    val g = myfunc 
    (n/g, d/g) 
    } 
} 
+0

啊,真的很簡單。我仍然對功能概念有直覺。 – skaffman 2009-07-13 12:30:07

+47

這實際上會爲您的班級添加一個隱藏的Tuple2字段。 – 2009-07-13 16:45:05

+2

這可能很重要。謝謝你的評論,豪爾赫。 – 2009-07-13 18:06:32

16

有幾種方法可以做到這一點。您可以在私有定義中聲明這樣的臨時變量,以便在施工期間使用。您可以在返回表達式的塊內使用臨時變量(例如在Alaz的回答中)。或者,最後,您可以在其他構造函數中使用這些變量。

以類似於替代構造函數的方式,您還可以在對象伴侶的「apply」方法中定義它們。

不能做的是聲明一個字段爲「臨時」。

還要注意,主構造函數接收的任何參數也是一個字段。如果你不希望這些參數成爲字段,也不想在構造函數中公開實際字段,那麼通常的解決方案是使主構造函數保持私有狀態,並使用實際字段,並使用其他構造函數或object-companion的apply()作爲有效的「主」構造函數。

6

有關這個主題的,包括馬丁·奧德斯基的評論一些討論,是here

11

我們有另一種方法是使主對象構造私人和使用一個同伴對象的應用方法作爲一個建設者。如果我們將(雙關語無意)這種方法您例如,它看起來就像這樣:

class R private (val x: Int, val y: Int); 

object R { 
    def apply(n: Int, d: Int): R = { 
    val g = myfunc; 
    new R(n/g, d/g); 
    } 
} 

要創建的R實例,而不是:

val r = new R(1, 2); 

寫:

val r = R(1, 2); 

這有點冗長,但可能會更糟,我想:)。讓我們希望在未來的Scala版本中,私有[this] vals將被視爲臨時變量。馬丁本人暗示說。

相關問題