使用视图时匹配错误

时间:2011-10-22 00:39:19

标签: scala view pattern-matching

List(1,2,3,4).sliding(2).map({ case List(a, b) => a < b }).forall(identity)

编译并返回true(虽然警告说匹配并非详尽无遗)。

List(1,2,3,4).view
   .sliding(2).map({ case List(a: Int, b: Int) => a < b }).forall(identity)

编译(只要我们包含ab的类型注释),但会抛出MatchError:

scala.MatchError: SeqViewC(...) (of class scala.collection.SeqViewLike$$anon$1)
        at $anonfun$1.apply(<console>:12)
        at $anonfun$1.apply(<console>:12)
        at scala.collection.Iterator$$anon$19.next(Iterator.scala:335)
        at scala.collection.Iterator$class.forall(Iterator.scala:663)
        at scala.collection.Iterator$$anon$19.forall(Iterator.scala:333)

为什么?

2 个答案:

答案 0 :(得分:7)

有趣的是,列表提取器List.unapplySeq无法提取SeqViewLike个对象,这就是为什么会出现匹配错误。但另一方面Seq可以。你可以这样看:

scala> val seqView = List(1,2).view.sliding(2).next
seqView: scala.collection.SeqView[Int,List[Int]] = SeqViewC(...)

scala> val List(a, b, _*) = seqView

scala.MatchError: SeqViewC(...) 

scala> val Seq(a, b, _*) = seqView
a: Int = 1
b: Int = 2

所以修复你的第二行是:

List(1,2,3,4).view.sliding(2).map({ case Seq(a, b) => a < b }).forall(identity)
// res: Boolean = true

所以问题是List(1,2,3,4).view会返回SeqView

请注意sliding已经返回Iterator,因此List(1,2,3,4).sliding(2)是懒惰的。可能不需要view

答案 1 :(得分:6)

好吧,列表视图不是列表,它是SeqView,它是Seq。以下是正确的事情:

List(1,2,3,4).view
   .sliding(2).map({ case Seq(a: Int, b: Int) => a < b }).forall(identity)