Scala 为什么不是';函数尾部不是递归的吗?
我正在读m.Odersky的Scala编程,他说 函数,例如近似函数,它们将自己称为最后一个函数 动作,称为尾部递归 所以,我试过这个:Scala 为什么不是';函数尾部不是递归的吗?,scala,recursion,tail-recursion,Scala,Recursion,Tail Recursion,我正在读m.Odersky的Scala编程,他说 函数,例如近似函数,它们将自己称为最后一个函数 动作,称为尾部递归 所以,我试过这个: object Main extends App { implicit val mc = new MyClass(8) val ti = new TestImplct ti.test } class TestImplct { def test(implicit mc : MyClass): Unit = { println(
object Main extends App {
implicit val mc = new MyClass(8)
val ti = new TestImplct
ti.test
}
class TestImplct {
def test(implicit mc : MyClass): Unit = {
println(mc.i)
mc.i -= 1
if(mc.i < 0){
throw new IllegalArgumentException
}
test
}
}
class MyClass(var i : Int)
这意味着它为每个递归调用生成一个新的堆栈帧。但最后的行动是呼吁自己。出了什么问题以及如何使其返回
为什么编译器不进行尾部调用优化?您可以尝试使用
@tailrec
注释标记该方法。若您这样做,编译将失败,并将向您展示为什么编译器无法将其优化为尾部递归:
Main.scala:12:错误:无法优化@tailrec注释的方法测试:它既不是私有的,也不是最终的,因此可以重写
事实上,如果您将方法设置为final,它将按预期工作。您的代码工作正常。
mc
对象中的值会随着每一步而减少。在最后一步,您将得到异常
例如,您可以将函数的返回类型更改为Boolean
,当值为<0
时返回false
,否则返回true
我建议您使用'@tailrec'注释,以便编译器检查递归函数调用。您在作用域中有MyClass的隐式实例吗?@Samar是的,我有。看看演示,我看你已经定义了这个类。但我看不出你在哪里实例化了它。@Samar啊,你说得对。我没有;不要附上完整的代码。我的同事们,很好用。你为什么认为它不是尾部递归的?它只是因为if条件而退出。有趣。为什么在这里使方法最终允许TCO?@Samar+1也想知道。正如错误所说:否则方法可能会被一些不是尾部递归的实现覆盖,那么您可能会认为您看到的是尾部递归,而实际上并非所有调用都能进行此优化。
Exception in thread "main" java.lang.IllegalArgumentException
at TestImplct.test(Main.scala:13)
at TestImplct.test(Main.scala:15)
at TestImplct.test(Main.scala:15)
at TestImplct.test(Main.scala:15)
at TestImplct.test(Main.scala:15)
at TestImplct.test(Main.scala:15)
at TestImplct.test(Main.scala:15)
at TestImplct.test(Main.scala:15)
at TestImplct.test(Main.scala:15)