如何在Scala中系统地避免不安全的模式匹配



考虑以下损坏的函数:

def sum (list : Seq[Int]) : Int = list match {
  case Nil => 0
  case head :: tail => head + sum(tail)
}

在这里,该函数本应使用List[Int],但被重构为接受Seq[Int],因此在编译器没有注意到的情况下被破坏。

Scala的不完全模式匹配检测中的这个巨大漏洞使它几乎毫无用处。

我想有一种系统地发现这些问题的方法。具体来说,我希望编译器在每个instanceof引导的模式匹配上都发出错误/警告,即我只希望允许在密封层次结构和自定义匹配器上进行模式匹配。

是否存在用于对模式匹配安全性进行保守(而不是任意)检查的现有编译器选项/插件?

看看M.Odersky的这个答案。

摘要

对非密封层次结构的匹配进行检查是可行的,并非微不足道,而且尚未实现。

Nil::显然是构造List的方法,但并非所有Seq的影响都恰好是Lists,因此可以预期Scala类型检查器会以类型错误为由拒绝此程序。正确的

错了。试试这个,你就会明白我的意思:

def sum (list : Seq[Int]) : Int = list match {
  case Nil => 0
  case head :: tail => head + sum(tail)
  case _ => -1
}
> sum(Array(1,2,3).toSeq)
res1: Int = -1
> sum(List(1,2,3))
res2: Int = 6

所以你看,一些Seq影响可能能够用Nil::解构,所以那些可以的,会的。那些做不到的人将在模式匹配中失败,然后继续前进,尝试下一场比赛。Nil::足以覆盖List的所有可能性,但不能覆盖Seq的所有可能性。在子类型、便利性和类型安全性之间有一个折衷。目前的解决方案是:重构时要更加小心。

相关内容

  • 没有找到相关文章

最新更新