爲什麼這是不可能的編譯這段代碼爲什麼無法與cons運算符匹配indexedSeq?
IndexedSeq(1, 2, 3) match {
case a :: b :: c => println("toto");
}
但它可能有一個序列?
IndexedSeq(1, 2, 3).toSeq match {
case a :: b :: c => println("toto");
}
IndexedSeq.toSeq
方法只是一個演員!
爲什麼這是不可能的編譯這段代碼爲什麼無法與cons運算符匹配indexedSeq?
IndexedSeq(1, 2, 3) match {
case a :: b :: c => println("toto");
}
但它可能有一個序列?
IndexedSeq(1, 2, 3).toSeq match {
case a :: b :: c => println("toto");
}
IndexedSeq.toSeq
方法只是一個演員!
我不知道爲什麼第二個編譯,但我知道它不起作用!
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");
}
爲了增加@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)
第一個例子並不編譯,因爲圖案a :: b :: c
的類型是List[something]
和選擇IndexedSeq(1, 2, 3)
的類型是IndexedSeq[Int]
。因爲List
不是IndexedSeq
的子類型,所以編譯器知道匹配不可能成功併產生錯誤。如the language specification(稍微修改以刪除公式)中所述:
每種模式都可以用兩種方式鍵入。首先,試圖將選擇器的類型作爲其預期類型來輸入模式。如果失敗,則改爲使用修改後的預期類型進行輸入,該修改後的預期類型是由
undefined
替換每次出現的類型參數後得到的。如果第二步也失敗,則會導致編譯時錯誤。
在第二種情況下,選擇的類型是Seq[Int]
,所以只要編譯器而言,它可能變成是一個List[Int]
在運行時,在這種情況下,它會成功。它可能會發出警告,說明匹配可能會失敗(事實上它的確如此),但Scala設計者另有決定:只有當選擇器的類型爲sealed
時纔會發出此警告。
* Seq只是一個返回適當集合的特性*它是一個'trait'使它能夠匹配'Cons'嗎? 'IndexedSeq [A]'也是一個'特徵'。 –
調用Seq(1,2,3)返回實現Cons的List(1,2,3)並不是它的特性,而是事實。 – sebszyller
但是'IndexedSeq(1,2,3).toSeq'返回一個'Vector [Int]'。 –