2014-01-22 124 views
2

我很難理解主構造函數及其參數的概念。我已經明白到現在爲止是:如果我們定義一個類如下scala中主要構造函數參數的可訪問性

class Example(a: Int, b: Int) 

Scala編譯器生成與上述兩個參數的類實例的主要構造。但是,它沒有定義字段 a b類別示例的定義。但是,如果我們定義

class Example(val a: Int, val b: Int) 

Scala編譯器生成的主構造如上,並增加了在類定義兩個字段。

現在的問題,當我試圖像

class PrimaryConstructor(a: Int, b: Int){ 
    override def toString() = "PrimaryConstructor(" + this.a + ", " + this.b + ")" 
} 

一個例子上面的代碼編譯好,即使沒有名爲領域既一個 b來。我無法理解,如果沒有任何字段,那麼我如何使用這個來訪問它們:當前的對象引用。

object Main{ 
    def main(args: Array[String]){ 
      val primaryConstructor = new PrimaryConstructor(1, 2) 
      println(primaryConstructor.a) 
    } 
} 

雖然如果我嘗試從上面的類定義的外側訪問它們,編譯後會出現以下錯誤消息。

error: value a is not a member of PrimaryConstructor 
    println(primaryConstructor.a) 

我可以理解這一點。但是,如何使用這個訪問這些字段?請幫我理解這一點。

+1

如果您有一些JavaScript經驗,請嘗試放棄Java類的概念,而將類視爲關閉(函數)作爲主構造函數中的參數。 「作爲封閉的一切」這個概念是scala的核心概念,一旦你喜歡它,它是非常強大的。主構造函數確保有一個類的關聯狀態的單一規範表示。 –

回答

3

它基本上產生私有纈氨酸,所以

class A(a:Int) { 
    def func = a 
} 

class A(private[this] val a:Int) { 
    def func = a 
} 

是等價的。如果您省略該功能,這可能並非完全正確。

當在構造函數體外引用構造函數參數時(例如上面的示例func),Scala會生成一個private[this] val,否則將生成一個private[this] val

您可以檢查斯卡拉規格的詳細信息,或看this stackoverflow question

+0

非常感謝。 我試圖用'javap -p PrimaryConstructor'反彙編來查看私有字段,並將它們全部顯示出來。 –

2

馬丁的答案是偉大的:

它基本上生成一個私人VAL,所以

class A(a:Int) { 
    def func = a 
} 

class A(private[this] val a:Int) { 
    def func = a 
} 

是等效的,您可以訪問a從你的班級裏面。

但是,請注意class A(a: Int)意味着字段a實例私有。這意味着你可以不寫這樣的事情:

class A(a: Int){ 
    def sum(other: A): Int = { 
    this.a + other.a 
    } 
} 

other.a是不允許的,即使這兩種情況下是相同類型的。您只能使用this.a

相關問題