【问题标题】:Multiple pattern matches with same input variable多个模式匹配相同的输入变量
【发布时间】:2013-04-02 17:09:45
【问题描述】:

我经常遇到以下问题:

val b = a match {
  case Some(a) => "1"
  case None => "n"
}
val c = a match {
  case Some(a) => "2"
  case None => "n"
}

显然,匹配执行了两次,即使它只需要一次。如何确保编译器考虑到这一点?

【问题讨论】:

    标签: scala pattern-matching match case


    【解决方案1】:

    我认为不会有任何性能提升,但您可以这样编写代码:

    val (b, c) = a match {
      case Some(a) => ("1","2)
      case None => ("n", "n")
    }
    

    【讨论】:

    • 看起来不错,但是如果 after=>-parts 是多行的呢?我将如何处理?
    • 对于编写的代码,这是一种性能损失,因为匹配速度非常快,但它仍然是反映两个新值依赖于一个旧值的好方法。因此,它可能是在没有性能问题(或匹配速度很慢)的情况下使用的更好模式。
    • 只是我的看法,我认为模式匹配选项通常是不必要的冗长。那怎么办? a.map(_ => ("1", "2")).getOrElse( ("n","n") )
    • +1... 我想为用户名和图标再+1 :)
    • @vtheron:对我来说,模式匹配为代码提供了一个组织良好的结构。您将如何使用getOrElse 编写多行代码?
    【解决方案2】:

    匹配可以非常快——与 if 语句相比。除非是一场艰难的比赛,否则不要担心重复工作。

    匹配默认值比匹配另一种情况稍微容易一些,所以如果你真的不需要这个参数,你最好的选择是

    val b = a match { case None => "n"; case _ => "1" }
    val c = a match { case None => "n"; case _ => "2" }
    

    这通常甚至会胜过诸如

    之类的可变解决方案
    var b,c = "n"
    a match { case Some(_) => b = "1"; c = "2"; case _ => }
    

    并且肯定会胜过任何元组创建。

    如果匹配是一个耗时的匹配,那么您必须存储结果并以元组或其他合适的数据结构返回它们,正如 om-nom-nom 已经证明的那样。这也可能更清楚,具体取决于上下文。

    【讨论】:

    • 输入两次也是两倍的工作。 :) 感谢您提醒注意额外分配,作为性能风格问题(作为一种习惯,在分析之前要做的事情)。
    猜你喜欢
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2010-11-13
    • 1970-01-01
    • 2013-12-04
    • 2016-09-24
    相关资源
    最近更新 更多