Scala 案例 类 和尾递归最佳实践

Scala case classes and tail recursion best practices

我是从 java 开始接触 Scala 的新手,也是模式匹配的新手。我试图解决的一件事是何时使用它以及它是什么 costs/benefits 。例如这个

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)
}

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

还有其他我应该担心的事情吗,比如资源?或者我应该几乎总是尝试使用模式匹配?

我搜索了这些答案,但没有找到任何 "best practices"!

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

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

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

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

  • 您有 3 个或更多选择
  • 您应该 unpack\check 值通过 extractors (check this question)
  • 你应该check the types

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

另一种 '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
  }

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

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

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