使用 trampoline 进行无堆栈递归(scala.util.control.TailCalls)
在调用递归函数时,通常会发生 StackOverflowError
错误。Scala 标准库提供 TailCall, 以通过使用堆对象和 continuation 来存储递归的本地状态来避免堆栈溢出。
来自 TailCalls 的 scaladoc 的两个例子
import scala.util.control.TailCalls._
def isEven(xs: List[Int]): TailRec[Boolean] =
if (xs.isEmpty) done(true) else tailcall(isOdd(xs.tail))
def isOdd(xs: List[Int]): TailRec[Boolean] =
if (xs.isEmpty) done(false) else tailcall(isEven(xs.tail))
// Does this List contain an even number of elements?
isEven((1 to 100000).toList).result
def fib(n: Int): TailRec[Int] =
if (n < 2) done(n) else for {
x <- tailcall(fib(n - 1))
y <- tailcall(fib(n - 2))
} yield (x + y)
// What is the 40th entry of the Fibonacci series?
fib(40).result