递归与尾递归
Scala中的循环都是通过递归(Recursive)实现的。递归的缺点是运算层层压在堆栈中,递归的层数过多时,很容易造成堆栈溢出的问题。Scala中利用尾递归(Tail Recursive Function)解决递归过程中可能导致的堆栈溢出的问题。
尾递归
所有递归形式的调用都出现在函数的末尾。当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中创建一个新的。
实例1:计算n!
递归方法实现n!的代码块如下:
def factorial(n: Int): Int =
if(n <= 0) 1
else n * factorial(n - 1)
尾递归方法实现n!的代码块如下:
@annotation.tailrec
def factorial(n: Int, m: Int): Int =
if( n<= 0) m
else factorial(n - 1, m * n)
注释
@annotation.tailrec
的作用是告诉编译器启动尾递归优化。参数n
表示阶乘的数字,参数m
表示累乘器,保存前面的递归调用的结果。m
拿到的一直是过去几次累乘的结果,因此只需要一个栈