2015-10-20 115 views
5

我很困惑斯卡拉構造。例如,我有以下類,它們表示具有運算符的樹,如樹上的Add和Leaf節點是數字。斯卡拉構造混亂 - 請澄清

abstract class Node(symbol: String) {} 

abstract class Operator(symbol: String, 
     binaryOp: (Double, Double) => Double) extends Node(symbol) { 
} 

class Add(a: Number, b: Number) extends 
     Operator("+", (a: Double, b: Double) => a+b) { 
} 

class Number(symbol: String) extends Node(symbol) { 
    val value = symbol.toDouble 
    def this(num: Double) { 
     this(num.toString) 
    } 
} 

我在一個網站上讀到什麼進去Scala的構造函數是自動不變(VAL),不過這傢伙對堆棧溢出說"The input parameters for the constructor are not vals unless you say they are."所以這是一個矛盾。

此外,我顯然可能會或可能不需要在構造函數中添加「val」和「override」出於某種原因?我的意思是我希望所有東西都是公共的,不可變的,添加的符號等於「+」,二進制等於加法函數,還有兩個數字a和b。有人可以請解釋如何使構造函數按照預期的方式在Scala中以非冗長的方式工作嗎?

我希望能夠做這樣的事情:

addition = Add(Number(1), Number(2)) 
addition.binaryOp(addition.a.value, addition.b.value) 
+0

REPL調用類參數vals。 'class C(x:Int){def mod(y:Int):Unit = x = y}'產生'錯誤:重新分配給val'。 – jwvh

回答

6

你就要成功了:每個參數Scala的類的構造函數是建設類的收起後拋出,除非的方法班級使用它。在這種情況下,它成爲private[this] val

但是,你可以簡單地添加val/var關鍵字在構造函數參數的前面,它會進行公開val/var

abstract class Node(val symbol: String) {} 

通常情況下,這不是在構造子類重複如果該字段的超已經定義:

abstract class Operator(symbol: String, // no val here, only pass to super class 
     val binaryOp: (Double, Double) => Double) extends Node(symbol) { 
} 

class Add(val a: Number, val b: Number) extends 
    Operator("+", (a: Double, b: Double) => a+b) { 
} 

現在你可以從類外部訪問字段:

addition = Add(Number(1), Number(2)) 
addition.binaryOp(addition.a.value, addition.b.value) 
+4

也可能值得一提的是案例類別有些不同(參數默認爲公共'vals's),因爲這可能是另一個混​​淆來源。 –