【问题标题】:match may not be exhaustive occurred when matching List匹配 List 时可能出现不详尽的匹配
【发布时间】:2016-01-17 07:57:51
【问题描述】:
val l = 1::2::Nil
l match{ case x :: y:: Nil => println(x,y)}

执行上述代码段时出现警告:

<console>:12: warning: match may not be exhaustive.
It would fail on the following inputs: List(_), List(_, _, _), Nil
       l match{ case x :: y:: Nil => println(x,y)}
       ^
(1,2)

但是,l match{ case List(x,y) =&gt; println(x,y)} 效果很好。 为什么?

【问题讨论】:

  • 为了澄清@dk14 的回答:最后一种情况实际上并不能很好地工作,它只是未能检测到可能的错误。要看到这一点,请更改为例如val l = 1 :: Nil:仍然没有警告,但是运行时会失败。

标签: list scala pattern-matching


【解决方案1】:

:: 是一个案例类(参见sources)。案例类自动检查穷举(如果继承自密封特征或密封抽象类),因此当您匹配 ::(x, ::(y, Nil)) 时,编译器可以做到这一点。有关更多信息,请参阅this article(请记住,案例类并不是 ADT,但他们可以对其进行建模)。

List(a,b) 只会导致从伴随对象调用List.unapplySeq(参见8.1.1 Extractor Patterns),这意味着编译器无法进行额外检查,因为它(简单地说)只是将case List(a,b) 转换为unapplySeq 调用.

这是一个检查所有可能输入的总函数示例:

l match { 
  case a :: b :: Nil => Some(a + b)
  case _ => None    
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    相关资源
    最近更新 更多