我正在尝试编写一个 100% 迭代的程序,也就是说,函数永远不需要返回,因为在这样的返回之后不会发生任何事情。
换句话说,程序100%处于尾部位置。考虑以下玩具程序:
def foo(): Unit =
bar()
def bar(): Unit =
foo()
try
foo()
catch
case s: StackOverflowError =>
println(" Stack overflow!")
Run Code Online (Sandbox Code Playgroud)
调用 foo 确实会导致堆栈溢出,这并不奇怪,事实上 foo 调用 bar,因为这样 bar 需要堆栈帧,bar 然后调用 foo,后者需要堆栈帧,等等。很明显为什么会发生堆栈溢出错误。
我的问题是,如何按原样定义 foo 和 bar 而不会出现堆栈溢出?像Scheme这样的语言允许这个程序,它们会永远运行,是的,但是堆栈不会增长,因为它知道调用后不需要发生任何事情,例如,来自foo的bar,所以不需要保留foo的堆栈帧呼叫酒吧。显然,scala(即 JVM?)确实使堆栈帧保持活动状态。
现在考虑下一个代码示例:
def foo(): Unit =
foo()
foo()
Run Code Online (Sandbox Code Playgroud)
该程序将永远运行,但永远不会发生堆栈溢出。
我知道 @tailrec 注释,但据我了解,它仅适用于第二个示例之类的情况,但不适用于第一个示例。
有任何想法吗?(我需要第一个示例像第二个示例一样永远运行,而不会出现堆栈溢出。)
recursion callstack scala tail-call-optimization stack-frame