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)
编译(只要我们包含a
和b
的类型注释),但会抛出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)
为什么?
答案 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)