來源:Scala中MEAP V10「應用」如何在Scala中的伴隨對象(使用Trait)中工作?
功能編程在下面粘貼代碼
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]
object List {
def sum(ints: List[Int]): Int = ints match {
case Nil => 0
case Cons(x,xs) => x + sum(xs)
}
def product(ds: List[Double]): Double = ds match {
case Nil => 1.0
case Cons(0.0, _) => 0.0
case Cons(x,xs) => x * product(xs)
}
def apply[A](as: A*): List[A] = {
if (as.isEmpty) Nil
else Cons(as.head, apply(as.tail: _*))
}
val example = Cons(1, Cons(2, Cons(3, Nil)))
}
的缺點目的通過推測構造應用(),但該類型的簽名是不同的,如何階最終組裝Cons實例。
也同時存在未申請,雖然下面的代碼工作絕對沒問題,拆開列表到缺點(頭,尾)
object a{
val x = List(1,2,3,4,5) match {
case Cons(x, Cons(2, Cons(4, _))) => x
case Nil => 42
case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y
case Cons(h, t) => h + List.sum(t)
case _ => 101
}
}
但如何斯卡拉知道它必須創建(頭,尾)的列表時實施那裏只有在適用方法,我接受關於可變參數的句法糖的提及,以及不適用於案例類的方法。 – 2014-09-26 14:52:52
我不是很確定我明白你的問題嗎?在編寫'MyObject(param)'時調用'MyObject.apply(param)'只是編譯器中實現的一種語言約定。 'apply'方法接受一個可變參數,在Scala中用一個'Seq'表示(而不是像Java中的數組),所以參數'as:A *'被用作參數'as:Seq [A]' 。 'apply'方法中的代碼然後使用這個'Seq'的公共方法來確定裏面的內容並調用正確的構造方法;如果它構造一個'Cons','apply'必須遞歸調用它來構造'Cons'的尾部。 – 2014-09-26 15:18:28
對不起,如果調用'Cons(1,Cons(2,Cons(3,Nil)))'會返回一個'List(1,2,3,Nil)',這是怎麼發生的? apply方法碰巧做了一個構造List實例並返回的技巧,但是當我看到類型簽名中的差異時讓我感到困惑 – 2014-09-26 15:32:56