【问题标题】:Does it make any sense to use pattern matching in Scala with really simple cases?在非常简单的情况下在 Scala 中使用模式匹配是否有意义?
【发布时间】:2012-01-28 02:56:16
【问题描述】:

在第 410 页的“Scala 编程,第二版”中,您可以找到具有以下方法的类 Simulation:

private def next() {
  (agenda: @unchecked) match {
    case item :: rest =>
      agenda = rest
      curtime = item.time
      item.action()
  }
}

我很好奇为什么 Odersky 使用模式匹配来实现这一点,而不是这样:

private def next() {
  val item = agenda.head
  agenda = agenda.tail
  curtime = item.time
  item.action()
}

模式匹配是否如此高效以至于根本无关紧要? 或者它只是不是那么完美的例子?

【问题讨论】:

    标签: scala pattern-matching scala-2.8 scala-collections


    【解决方案1】:

    通常我会按照你的方式来写。 (尽管模式匹配非常有效,但不如头/尾高效。)如果

    1. 你想练习模式匹配
    2. 您想要MatchException 而不是NoSuchElementException
    3. 您打算稍后填写其他案例。

    【讨论】:

      【解决方案2】:

      有几个原因:

      1. 本书的部分重点是让您以 Scala(函数式)术语进行思考;模式匹配是函数式编程的等价物。

      2. 模式匹配和函数式方法是Scala中的自然模式,并以自然的方式允许并发之类的事情;了解该模式,您的 Scala 程序将准备好用于更高级的用途。

      【讨论】:

        【解决方案3】:

        模式匹配在 Scala 中更惯用,并且更容易保护您免受边界条件的影响。

        在代码中

        private def next() {
          val item = agenda.head
          agenda = agenda.tail
          curtime = item.time
          item.action()
        }
        

        如果agenda 是一个空列表,agenda.head 和agenda.tail 都会抛出一个NoSuchElementException 异常,因此要使其实际工作,您需要为此添加一个检查。

        模式匹配版本实际上有一个类似的问题(如 th cmets 中所述),但我发现修复更简洁,因为您所要做的就是添加另一个模式:

        private def next() {
          (agenda: @unchecked) match {
            case item :: rest =>
              agenda = rest
              curtime = item.time
              item.action()
            case _ => {}
          }
        }
        

        【讨论】:

        • 如果模式不匹配,模式匹配版本会抛出MatchException
        • @gerferra:我的立场是正确的。但无论如何,模式匹配版本都有一个简单的修复。我会更新答案。
        • 另一个版本也有一个简单的修复:要么包裹在if (!agenda.isEmpty)中,要么使用agenda.headOption.foreach{ item => agenda = agenda.tail; curtime = item.time; item.action() }
        【解决方案4】:

        我的猜测是首先这里不用担心异常,在调用这个“下一个”方法之前可能会进行一些检查。事实上,这可能也是“未选中”注解的原因,所以他真的不必多放一个case _ =>。我认为推理更多的是他想使用“不适用”。这里没有模式匹配的替代方案,但也没有 head 和 tail 可能是这样的:

        private def next() {  
            val item :: rest = agenda
            agenda = rest
            curtime = item.time
            item.action()
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-01-25
          • 2017-10-28
          • 2011-04-08
          • 1970-01-01
          • 2021-08-12
          • 2014-05-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多