【问题标题】:Match order with an extractor将订单与提取器匹配
【发布时间】:2011-12-12 13:22:08
【问题描述】:

我定义了一个自定义提取器来获取列表的最后一个元素,如https://stackoverflow.com/a/6697749/1092910

object :+ {
  def unapply[A](l: List[A]): Option[(List[A], A)] = {
    if (l.isEmpty)
      None
    else 
      Some(l.init, l.last)
  }
}

现在这匹配“好”:

List(1, 2, 3) match {
  case init :+ last => "good"
  case head :: tail => "bad"
}

但是如果我添加另一个子句,它现在突然匹配“坏”:

List(1, 2, 3) match {
  case List(7) => "never"
  case init :+ last => "good"
  case head :: tail => "bad"
}

这种行为的原因是什么?

【问题讨论】:

  • 它看起来像一个错误。我可以尝试在其中一个邮件列表上提问。
  • scalac -print 编译,看来编译器正在对模式进行一些优化,并合并了List(7)head :: tail 的测试。它首先检查它是否是一个 Int 列表,然后检查第一个元素是否为 7,如果不是,它立即落入head::tail 并匹配head::tail。这似乎确实是编译器中的一个错误。

标签: scala match extractor


【解决方案1】:

它是 #1697/2337 和一打重复。

https://issues.scala-lang.org/browse/SI-1697

可以肯定地说,它不会直接修复,而是删除 virtpatmat 实现的模式匹配器。尝试最近的构建并使用 -Yvirtpatmat 进行编译,您会得到正确的答案。

【讨论】:

    猜你喜欢
    • 2015-08-08
    • 1970-01-01
    • 2020-01-12
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 2020-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多