为什么 scala 编译器没有标记似乎不是尾递归函数的东西



我已经标记了方法sameLength来检查和优化尾递归。我觉得相同长度方法中的最后一个操作不是相同长度。它是&&。&&在else子句中。为什么编译器不标记这一点。由于编译器没有标记它,因此我认为它确实是尾递归的。有人可以为我定义尾递归吗?我脑子里有错误的定义。

  import scala.annotation.tailrec

  object TestTailRec extends App{
    @tailrec
    def sameLength[T](xs: List[T], ys: List[T]) : Boolean = {
      if(xs.isEmpty) ys.isEmpty
      else ys.nonEmpty && sameLength(xs.tail, ys.tail)
    }
    println(sameLength(List(1,2,3), List(1,2,3)))
  }

规范定义了Boolean&&方法。

由于 Boolean 是值类,因此if/else表达式是内联的。

由于 p 参数是按名称计算的,因此不会先对其进行计算。

您的直觉被严格版本所证实:

scala> @tailrec def f(i: Int): Boolean = false & f(i)
<console>:16: error: could not optimize @tailrec annotated method f: it contains a recursive call not in tail position
让我们稍微

重构一下你的方法,而不改变它的含义:

def sameLength[T](xs: List[T], ys: List[T]) : Boolean = {
  if(xs.isEmpty) ys.isEmpty
  else if (ys.isEmpty) false else
  sameLength(xs.tail, ys.tail)
}

我认为现在很清楚这是尾递归

最新更新