ADT上的Scala模式匹配可能无法在无法访问的代码上发出警告

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ADT上的Scala模式匹配可能无法在无法访问的代码上发出警告相关的知识,希望对你有一定的参考价值。

我有一个简单的ADT(代数数据类型)编码为:

sealed trait TrafficLight
case object Red extends TrafficLight
case object Green extends TrafficLight
case object Yellow extends TrafficLight

说,我有一个返回TrafficLight颜色名称的函数:

  def getColour(tf: TrafficLight): String = tf match {
    case Red    => "red"
    case Green  => "green"
    case Yellow => "yellow"
  }

这按预期工作。现在我已经在上面的函数中匹配了TrafficLight的所有情况。如果我在同一方法的底部引入默认匹配:

  def getColour(tf: TrafficLight): String = tf match {
    case Red    => "red"
    case Green  => "green"
    case Yellow => "yellow"
    case other  => "unknown" //this should not be unreachable
  }

编译器没有警告我case other无法访问。我还启用了编译器标志:-Ywarn-dead-code。这是否意味着Scala无法推断我已经涵盖了TrafficLight ADT的所有可能值?

这似乎不太可能,因为如果我将getColour的定义更改为:

def blah(tf: TrafficLight): String = tf match {
  case Red    => "red"
  case Green  => "green"
}

编译器警告我,我错过了一个案例:

> match may not be exhaustive.
> [error] It would fail on the following input: Yellow
> [error]   def blah(tf: TrafficLight): String = tf match {

我正在使用Scala 2.12.5

这是一个错误还是我做了错误的假设?

答案

您没有涵盖TrafficLight的所有可能变体,您刚刚涵盖了所有已命名的变体,但您仍然可以传递匿名类对象作为参数fe。:

getColour(new TrafficLight {})

以上是关于ADT上的Scala模式匹配可能无法在无法访问的代码上发出警告的主要内容,如果未能解决你的问题,请参考以下文章

使用Scala宏无法解释的类型不匹配

使用构造函数scala上的模式匹配键入不匹配

安装 ADT 插件后无法打开 Eclipse

Scala 模式匹配详解

【Scala】模式匹配和样本类

scala模式匹配的一个问题