【问题标题】:Match error while using view使用视图时匹配错误
【发布时间】:2011-10-22 00:39:19
【问题描述】:
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)

为什么?

【问题讨论】:

  • sliding 返回一个Iterator,因此在view 上调用它不会带来任何好处。

标签: scala view pattern-matching


【解决方案1】:

这很有趣,列表提取器 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 是不必要的。

【讨论】:

    【解决方案2】:

    嗯,列表的视图不是列表,它是一个SeqView,它是一个Seq。以下是正确的:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      • 2012-08-04
      • 2020-03-09
      • 1970-01-01
      • 1970-01-01
      • 2018-11-11
      • 1970-01-01
      相关资源
      最近更新 更多