我有以下功能:
@tailrec
def samePrefix[A](length: Int)(a: Vector[A], b: Vector[A]): Boolean = {
if(length<1) true
else{
if(a(length-1)==b(length-1)) samePrefix(length-1)(a, b)
else false
}
}
检查两个向量是否具有相等的第一个元素,给定一个要检查的长度。
我想知道是否调用
的部分samePrefix(length-1)(a, b)
首先从samePrefix(length-1)
创建一个函数对象,然后将(a,b)
应用于它,或者如果它只是递归地调用我的方法。
答案 0 :(得分:5)
让我们看看......
$ scala
Welcome to Scala version 2.11.1
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.annotation._
import scala.annotation._
scala> @tailrec def curried(a: Int)(b: Int): Int = curried(a-1)(b-1)
curried: (a: Int)(b: Int)Int
scala> :javap curried
... irrelevant output removed ...
public int curried(int, int);
flags: ACC_PUBLIC
Code:
stack=3, locals=3, args_size=3
0: iload_1
1: iconst_1
2: isub
3: iload_2
4: iconst_1
5: isub
6: istore_2
7: istore_1
8: goto 0
... irrelevant output removed ...
如您所见,字节码中没有递归调用。相反,有一条goto 0
指令表示循环。这意味着尾调用优化已经发生。
您还会注意到,已编译的字节码中已将多个参数列表压缩为单个参数列表,因此不涉及中间函数。
编辑:实际上,我们没有必要检查字节码,以确保该方法已使用TCO进行编译,因为@tailrec
注释完全存在于此目的。换句话说,如果你将@tailrec
放在你的方法上并且编译没有错误,你可以100%确定它是用TCO编译的。