23

我怎么能压制“匹配不是穷举”!以下 Scala 代码中的警告?

val l = "1" :: "2" :: Nil
l.sliding(2).foreach{case List(a,b) => }

到目前为止,我发现的唯一解决方案是用附加的 match 语句围绕模式匹配:

l.sliding(2).foreach{x => (x: @unchecked) match {case List(a,b) => }}

然而,这使得代码变得不必要地复杂并且非常难以阅读。所以必须有一个更短、更易读的替代方案。有人知道吗?

编辑

我忘了提到我的列表l在我的程序中至少有 2 个元素。这就是为什么我可以安全地抑制警告。

4

4 回答 4

21

这里有几个选项:

  1. 您可以匹配Seq而不是List,因为Seq没有详尽检查(这将失败,就像您原来的一样,在一个元素列表上):

    l.sliding(2).foreach{case Seq(a, b) => ... }
    
  2. 您可以使用 for 理解,它会默默地丢弃任何不匹配的内容(因此它不会在一个元素列表上执行任何操作):

    for (List(a, b) <- l.sliding(2)) { ... }
    
  3. 您可以使用collect,它也会默默地丢弃任何不匹配的东西(以及在哪里获得迭代器,如果需要,您必须遍历它):

    l.sliding(2).collect{case List(a,b) => }.toList
    
于 2012-11-05T11:24:53.153 回答
20

完成它; case _ => ???很短。 ???只是抛出一个异常。如果您使用的是 2.9 或更早版本(它是 2.10 中的新功能),您可以定义自己的。

与匹配注释所需的相比,它确实很短:

(: @unchecked)
; case _ => ???
              ^  One more character!

它不会抛出 a MatchError,但这真的很重要吗?

于 2012-11-05T10:20:14.863 回答
3

由于您sliding(2)可能返回最后一个列表,其中只有一个元素,因此您还应该对其进行测试:

l sliding(2) foreach {
  case a::b::Nil => println("two elements: " + a + b)
  case l         => println("one last element" + l.head)
}
于 2012-11-05T10:27:04.107 回答
1
implicit class RichAny[A](private val a: A) extends AnyVal {
  @inline
  def match_ignoring_nonexhaustive[B](f: PartialFunction[A,B]): B = f(a)
}

有了这个,您可以执行以下操作,实际上仅将大小写匹配解释为 PartialFunction:

l.sliding(2).foreach{ _ match_ignoring_nonexhaustive {case List(a,b) => }}
于 2017-01-09T18:19:59.827 回答