在Scala 2.11中进行模式匹配的穷举检查

时间:2015-12-01 13:54:10

标签: scala pattern-matching

我们有一些模式匹配代码,我们期望编译器警告匹配并非详尽无遗,但我们没有。是否有些情况无法进行穷举检查?

例如我们的例子(使用scalactic Good + Bad):

(maybeModelIdOrFailure, maybeMake) match {

    case (Some(Good(modelId)), Some(makeId)) if modelId >= 0 && taxonomyService.isValidModel(makeId, modelId) =>
      Good(Some(MakeModelParameters(makeId, Some(modelId), modelLineId = None, index)))

    case (Some(Good(modelLineId)), Some(makeId)) if modelLineId < 0 && taxonomyService.isValidModelLine(makeId, -1 * modelLineId) =>
      Good(Some(MakeModelParameters(makeId, modelId = None, modelLineId = Some(-1 * modelLineId), index)))

    case (Some(Good(modelOrModelLineId)), Some(makeId)) =>
      Bad(One(IdNotFound(modelIdKeyName, modelOrModelLineId)))

    case (Some(Good(modelId)), None) if modelId >= 0 =>
      Bad(One(IdInvalid(modelIdKeyName, "Model Id without Make Id")))

    case (Some(Good(modelLineId)), None) if modelLineId < 0 =>
      Bad(One(IdInvalid(modelIdKeyName, "Model Line Id without Make Id")))

    case (None, Some(makeId)) => Good(Some(MakeModelParameters(makeId, None, None, index)))

    // case (None, None) => Good(None)

    // case (Some(Bad(invalidParams)), _) => Bad(One(invalidParams))
  }

我们评论了最后两行,但编译器没有发出警告,我们也没有禁用任何检查。

2 个答案:

答案 0 :(得分:6)

Jason Zaugg's comment on SI-9232来看,警卫目前似乎只是禁用详尽检查(或几乎如此)。如果这是原因,移动分支内的保护条件(例如case (Some(Good(modelId)), None) => if (modelId >= 0) ... else ...)应该会有所帮助。其他相关问题:https://issues.scala-lang.org/browse/SI-5365https://issues.scala-lang.org/browse/SI-7631

答案 1 :(得分:4)

如果你在比赛中有任何后卫,看起来scala只是关闭穷举检查。我的编译器甚至不会发出警告:

def tt(s: Option[Int]) = s match {
  case Some(x) if x > 0 => println(x)
}

只要我守卫那里。门票上有关于此的讨论: https://issues.scala-lang.org/browse/SI-7631 https://issues.scala-lang.org/browse/SI-5365 看起来这里有一些工作要做,所以它可能会有所改进。在大多数情况下,Scala编译器无法检查守卫的详尽性,因为这样做太复杂了,但是你的情况肯定证明它可以得到改进。