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

标签 scala pattern-matching algebraic-data-types

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

sealed trait TrafficLight
case object Red extends TrafficLight
case object Green extends TrafficLight
case object Yellow extends 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 模式匹配可能不会对无法访问的代码发出警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52166951/

相关文章:

scala集合函数不同的调用方式

斯卡拉 SortedMap : Get all keys greater than a given key

.net - 为什么点符号在此正则表达式中不起作用?

java - 如何匹配模式正则表达式中 token 的最后一个实例?

vector - IDRIS向量与链表

types - 在调用函数和回调之间对齐多态变体类型

scala - Play 2.0 模型最佳实践

algorithm - 计算子串的数量

scala - 向 Scala 案例类添加方法是个好主意吗

scala - 如何确保内联类型匹配(scala 3)中的两个参数引用相同的类型