【问题标题】:Scala case classes and tail recursion best practicesScala 案例类和尾递归最佳实践
【发布时间】:2015-06-25 14:52:15
【问题描述】:

我对 java 的 scala 还很陌生,对模式匹配也很陌生。我试图弄清楚的一件事是何时使用它以及它的成本/收益是什么。比如这个

def myThing(a: Int): Int = a match {
  case a: Int if a > 0 => a
  case _ => myThing(a + 1)
}

和这个做同样的事情(除非我真的误解了什么)

def myThing(a: Int): Int = {
  if (a > 0) a
  else myThing(a + 1)
}

所以我的实际问题是: 但是它们的运行方式相同吗?我的模式匹配示例尾递归吗?如果不是,那为什么不在第二个例子中呢?

还有什么我需要担心的,比如资源?还是我应该总是尝试使用模式匹配?

我搜索了这些答案,但没有找到任何“最佳实践”!

编辑:我知道使用的示例有点做作 - 我刚刚添加它是为了清楚下面的问题 - 谢谢!

【问题讨论】:

    标签: scala recursion pattern-matching tail-recursion case-class


    【解决方案1】:

    是的,它们的运行方式相同。每个语法糖的最佳实践都是相同的:只要它提供更易读或更灵活的代码,就使用它。在if 语句的示例中,您可以省略大括号并只写

    def myThing(a: Int): Int =  if (a > 0) a else myThing(a + 1)
    

    这绝对比模式匹配更方便。模式匹配在以下情况下很方便:

    也可以使用to ensure you function is tail-recursive @tailrec 注释

    【讨论】:

      【解决方案2】:

      另一种“Scala”方法是为正数定义一个提取器

        def myThing(a: Int): Int = a match {
          case PositiveNum(positive) => positive
          case negative => myThing(negative + 1)
        }
      
      
        object PositiveNum {
          def unapply(n: Int): Option[Int] = if (n > 0) Some(n) else None
        }
      

      【讨论】:

      • 在这种情况下有点矫枉过正,但在更复杂的情况下非常有用。
      【解决方案3】:

      另一种对评估的谓词(条件)进行模式匹配的方法,

      def myThing(a: Int): Int = a > 0 match {
        case true => a
        case _    => myThing(a + 1)
      }
      

      匹配项不包括(额外的)保护或类型声明。

      【讨论】:

      • 这很混乱(至少对我来说),那么这样写有什么好处呢?
      • 最好的方法是 if-else 表达式;对于模式匹配,这证明比原来的更简洁,没有保护,没有额外的类型声明。
      猜你喜欢
      • 2014-12-20
      • 1970-01-01
      • 2011-02-13
      • 2020-07-13
      • 1970-01-01
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      • 2014-11-18
      相关资源
      最近更新 更多