Stack Overflow 上有各种答案,解释了在Scala中可以进行尾递归的条件。我了解限制以及如何以及在何处可以利用尾递归。我不明白的部分是为什么存在对私有或最终方法的限制。
我还没有研究过 Scala 编译器实际上是如何在字节码级别将递归函数转换为非递归函数的,但让我们假设它执行以下操作。我有一个Foo
带有递归函数的类mod
:
class Foo {
def mod(value: Int, denom: Int): Int = {
if(denom <= 0 || value <= 0) 0
else if(0 <= value && value < denom) value
else mod(value - denom, denom)
}
}
这是一个基本的模函数,我想 Scala 编译器会转换为某种伪 Java-Scala,例如:
class Foo {
def mod(value: Int, denom: Int): Int = {
if(denom <= 0 || value <= 0) return 0
while(value > denom) value -= denom
return value
}
}
(我可以相信我把翻译搞砸了,但我认为细节并不重要..)
所以现在假设我是子类Foo
:
class Bar extends Foo {
def mod(value:Int, denom: Int): Int = 1
}
是什么阻止了它的工作?当JVM有aFoo/Bar
并且mod
在上面调用的时候,为什么解析mod
应该使用的函数会出现问题。为什么这与基函数非递归的情况有什么不同?
我认为出现这种情况的几个可能原因是:
无论出于何种原因,Scala 编译器的实现都无法处理这个问题(如果是这样的话,那就足够了。如果是这样,是否有计划改变这个?)
in函数
Foo
在编译期间被修改,因此实际上没有方法可以覆盖。mod
mod-non-recursive
Foo
mod