2015-11-01 40 views
2

我試圖創建一個案例類有多個構造函數:如何在案例類中指定多個構造函數?

object App { 
    def main(args: Array[String]) { 
    val a = Something("abc", 100500, _ % 2 == 0) 
    val b = Something(true, 10, 20) 
    println(s"$a - $b") 
    } 
} 

case class Something(s: String, n: Int, p: Int => Boolean) { 
    /* 
    Additional constructor -- Wrong way! -- it is imposible to invoke it outside the class 
    def this(b: Boolean, x: Int, y: Int) { 
    this("", 0, (i: Int) => i % x + y == 0) 
    } 
    */ 
} 

到目前爲止,我的代碼不起作用:

Error:(10, 23) type mismatch; 
found : Boolean(true) 
required: String 
    val b = Something(true, 10, 20) 
        ^

要解決它,我需要創建一個同伴對象持有一個apply功能,代表一種新的構造函數Something類:

object Something {  
    def apply(b: Boolean, x: Int, y: Int) = { 
    new Something(if (b) "" else "default", 0, _ => { 
     (x + y) % 2 == 0 
    }) 
    } 
} 

這是不方便的。也許有其他方法可以將多個構造函數放入case類中?

+0

我覺得同伴對象是唯一的出路因爲case類是代數類型的,它不應該有不同的形式(不同的構造函數)。如果你可以爲它創建輔助構造函數 - 我認爲它不會很好地適用於所有的case類功能 - 比如模式匹配 – Archeg

+0

你提到了一個代數類型。所以我在wiki中檢查了它是什麼意思,並發現這一點:'每個變體都有自己的構造函數,它使用指定類型的指定數量的參數。「所以代數類型允許多個構造函數。 – Finkelson

+0

我認爲不相交意味着:'抽象類Base;案例類A(i:Int)擴展了Base; case class B(s:String)extends Base'現在,您可以使用'Integer'或'String'類型進行類型化,這是'Base'的兩個構造函數。但它看起來不像解決你的問題。 – Archeg

回答

10

其實它的工作原理,但你必須使用new作爲輔助構造函數沒有做的情況下類生成apply:如果你想Something(true, 5, 5)工作

​​

,你需要像你說的創建同伴對象。我認爲這是因爲否則案例類將無法像現在這樣使用模式匹配,否則它會變得更加複雜。並注意模式匹配不會在這種情況下工作

還記得,案例類支持默認構造函數像case class Something(s: String = "default")這可能會幫助你,但它不解決您的例子不幸

相關問題