2016-07-06 56 views

回答

4

我不知道爲什麼第二個編譯,但我知道它不起作用!

scala> IndexedSeq(1,2, 3).toSeq match { 
    case a :: b :: c :: nil => println("toto"); 
} 
    |  | scala.MatchError: Vector(1, 2, 3) (of class scala.collection.immutable.Vector) 

如果你想匹配模式的序列,您可能需要使用+:作爲聯合運營商,或使用SEQ(A,B,C)如要匹配的模式。見this answer

以下作爲一切工作的期望:

IndexedSeq(1,2, 3).toSeq match { 
    case Seq(a, b, c) => println("toto"); 
} 

IndexedSeq(1,2, 3) match { 
    case Seq(a, b, c) => println("toto"); 
} 

IndexedSeq(1,2, 3).toSeq match { 
    case a +: b +: c => println("toto"); 
} 

IndexedSeq(1,2, 3) match { 
    case a +: b +: c => println("toto"); 
} 
1

爲了增加@ladams的答案。在IndexedSeq上調用toSeq只是指超級,因爲後者從前者繼承。在側面說明,你也可以提取值的方式如下:

IndexedSeq(1, 2, 3) match { 
    case IndexedSeq(head, tail @ _*) => println("got match") 
    case _ => println("sth else") 
    } 

此外,SEQ僅僅是適當的返回集合的性狀,例如

val s: Seq[Int] = 1 :: 2 :: 3 :: Nil 
s: Seq[Int] = List(1, 2, 3) 

因此,您可以將其與缺點匹配。而IndexedSeq返回一個Vector,它沒有定義Cons操作符。

val s: IndexedSeq[Int] = IndexedSeq(1, 2, 3) 
s: IndexedSequence[Int] = Vector(1, 2, 3) 
+0

* Seq只是一個返回適當集合的特性*它是一個'trait'使它能夠匹配'Cons'嗎? 'IndexedSeq [A]'也是一個'特徵'。 –

+0

調用Seq(1,2,3)返回實現Cons的List(1,2,3)並不是它的特性,而是事實。 – sebszyller

+0

但是'IndexedSeq(1,2,3).toSeq'返回一個'Vector [Int]'。 –

1

第一個例子並不編譯,因爲圖案a :: b :: c的類型是List[something]和選擇IndexedSeq(1, 2, 3)的類型是IndexedSeq[Int]。因爲List不是IndexedSeq的子類型,所以編譯器知道匹配不可能成功併產生錯誤。如the language specification(稍微修改以刪除公式)中所述:

每種模式都可以用兩種方式鍵入。首先,試圖將選擇器的類型作爲其預期類型來輸入模式。如果失敗,則改爲使用修改後的預期類型進行輸入,該修改後的預期類型是由undefined替換每次出現的類型參數後得到的。如果第二步也失敗,則會導致編譯時錯誤。

在第二種情況下,選擇的類型是Seq[Int],所以只要編譯器而言,它可能變成是一個List[Int]在運行時,在這種情況下,它會成功。它可能會發出警告,說明匹配可能會失敗(事實上它的確如此),但Scala設計者另有決定:只有當選擇器的類型爲sealed時纔會發出此警告。