2016-12-27 244 views
0

在斯卡拉開始我的第一步,我遇到了第一個誤解。
我拿了一個鏈表的典型例子。斯卡拉鍊接列表

sealed trait List[+A] // `List` data type, parameterized on a type, `A` 
case object Nil extends List[Nothing] // A `List` data constructor representing the empty list 
/* Another data constructor, representing nonempty lists. Note that `tail` is another `List[A]`, 
which may be `Nil` or another `Cons`. 
*/ 
case class Cons[+A](head: A, tail: List[A]) extends List[A] 

object List { // `List` companion object. Contains functions for creating and working with lists. 
    def sum(ints: List[Int]): Int = ints match { // A function that uses pattern matching to add up a list of integers 
    case Nil => 0 // The sum of the empty list is 0. 
    case Cons(x,xs) => x + sum(xs) // The sum of a list starting with `x` is `x` plus the sum of the rest of the list. 
    } 

    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] = // Variadic function syntax 
    if (as.isEmpty) Nil 
    else Cons(as.head, apply(as.tail: _*)) 

    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 + sum(t) 
    case _ => 101 
    } 
} 

有幾個問題:
1)爲什麼自定義鏈表類並不衝突內置scala.collection.immutable.List.type

2)爲什麼一段代碼被認爲當我們是正確的將內置List與自定義鏈表進行匹配?

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 + sum(t) 
    case _ => 101 
    } 

回答

1
  1. 自定義鏈接列表類不會有衝突的內置scala.collection.immutable.List.type因爲局部聲明,如您的自定義列表類型,具有比進口高優先級(甚至是非明確的那些,作爲斯卡拉的內置List)。有關完整的優先順序,請參閱Scala Specification的第2章。

  2. 引用的匹配代碼不匹配內置列表,而是您自己的本地聲明列表。您可以自己查看它,方法是將您的List重命名爲CustomList之類的內容,並查看是否會出現一些錯誤,或者完全限定內置列表,如下面的代碼所示。

下面的代碼確實匹配您的自定義列表結構內置列表,並不會編譯:

val x = scala.collection.immutable.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 + sum(t) 
    case _ => 101 
    } 
+0

感謝您的回覆。但是如何使用建築清單(1,2,3,4,5)呢?應用方法有這樣的機會嗎? –

+2

您正在調用'List'對象的'apply [A](as:A *):List [A]'方法。 –

1

你的問題實際上是關於範圍,我相信。您已經定義了自己的列表,它與scala.collection.immutable中的無關...與Cons和Nil相同。

當您在第2部分中實例化列表時),您正在實例化您的List,而不是Scala庫中的List。

或者我錯過了什麼?