2012-07-16 137 views
18
val x = for(i <- 1 to 3) yield i 
x match { 
    case 1 :: rest => ... // compile error 
} 

constructor cannot be instantiated to expected type; found : collection.immutable.::[B] required: scala.collection.immutable.IndexedSeq[Int]模式匹配序列理解的慣用方式是什麼?

這是同樣的問題MatchError when match receives an IndexedSeq but not a LinearSeq

問題是,怎麼做對不對?到處添加.toList似乎不正確。並創建一個處理每個Seq(如其他問題的答案中所述)的自己的提取器將導致一個混亂,如果每個人都會這樣做...

我想問題是,爲什麼我不能影響什麼序列綜合的返回類型是,或者:爲什麼不是標準庫的這種廣義化的提取器部分?

+5

這個廣義的提取器在2.10中可用:'val a +:b = 0直到10'像'val a :: b =(0至10).toList'在2.9中那樣工作。 – 2012-07-16 11:16:49

+0

嗯,非常有趣!雖然我不確定它是否也會爲列表創建一個有兩個提取器的混亂。這個提取器是否應該取代::?畢竟,它可以做同樣的事情,更通用。 – letmaik 2012-07-16 11:28:50

+1

@TravisBrown這是很好的知道。是否還有List的'Nil'的等價物? – 2012-07-16 15:38:36

回答

36

那麼,你可以圖案匹配任何序列:

case Seq(a, b, rest @ _ *) => 

例如:

scala> def mtch(s: Seq[Int]) = s match { 
    |  case Seq(a, b, rest @ _ *) => println("Found " + a + " and " + b) 
    |  case _ => println("Bah") 
    | } 
mtch: (s: Seq[Int])Unit 

那麼這將任何序列具有大於(或等於)匹配2個元件

scala> mtch(List(1, 2, 3, 4)) 
Found 1 and 2 

scala> mtch(Seq(1, 2, 3)) 
Found 1 and 2 

scala> mtch(Vector(1, 2)) 
Found 1 and 2 

scala> mtch(Vector(1)) 
Bah 
+0

我得到scala.MatchError:Vector(1,2,3)(類scala.collection.immutable.Vector)。難道只能匹配那樣的案例類嗎? – letmaik 2012-07-16 11:25:57

+0

糟糕 - 抱歉 - 錯過了一個'*' – 2012-07-16 11:56:11

+0

可以將任何內容與提取器進行匹配 - 在這種情況下,使用'unapplySeq'方法的任何內容都是可能的。 – 2012-07-16 12:01:51