我对 Scala 有点陌生,在阅读 David Pollack 的《Begining Scala》时尝试了它。
他定义了一个简单的递归函数,从文件中加载所有字符串:
def allStrings(expr: => String): List[String] = expr match {
case null => Nil
case w => w :: allStrings(expr)
}
它很优雅而且很棒,只是当我尝试加载一个巨大的字典文件时它抛出了 StackOverflow 异常。
现在据我了解Scala支持尾递归,因此函数调用不可能溢出堆栈,可能编译器无法识别它?因此,经过一番谷歌搜索后,我尝试了 @tailrec 注释来帮助编译器,但它说
error: could not optimize @tailrec annotated method: it contains a recursive call not in tail position
def allStrings(expr: => String): List[String] =
我对尾递归的理解错误吗?我该如何修复此代码?
仅当最后一次调用是对方法本身的调用时,Scala 才能对此进行优化。
好吧,最后的电话不是allStrings
,实际上是到::
(缺点)方法。
使尾递归的一种方法是添加累加器参数,例如:
def allStrings(expr: => String, acc: List[String] = Nil): List[String] =
expr match {
case null => acc
case w => allStrings(expr, w :: acc)
}
为了防止累加器泄漏到 API 中,您可以将尾递归方法定义为嵌套方法:
def allStrings(expr: => String) = {
def iter(expr: => String, acc: List[String]): List[String] =
expr match {
case null => acc
case w => iter(expr, w :: acc)
}
iter(expr, Nil)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)