Scala和尾递归
Stack Overflow上有各种答案,它解释了
Scala中尾递归的可能条件.我理解了局限性以及如何以及在哪里可以利用尾递归.我不理解的部分是为什么存在对私有或最终方法的限制.
我还没有研究过Scala编译器如何在字节码级别将递归函数实际转换为非递归函数,但我们假设它执行类似下面的操作.我有一个带有递归函数mod的类Foo: 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有一个Foo / Bar并调用mod时,为什么解析应该使用的mod函数会有问题.为什么这与基函数是非递归的情况有什么不同? 我可以看到的一些可能的原因是: >无论出于何种原因,Scala编译器的实现都不能处理这个问题(如果是这样的话就足够了.如果是这样,是否有计划改变这个?) 解决方法
我刚刚回答了这个问题,但让我们举个例子.假设您定义了类Foo,并将其作为JAR文件提供.
然后我得到那个Jar文件,并以这种方式扩展你的Foo: class Bar extends Foo { def mod(value:Int,denom: Int): Int = { Logger.log("Received mod with "+value+" % "+denom) super.mod(value,denom) } 现在,当Foo的mod调用自己时,因为我的对象是一个Bar而不是Foo,你应该(并且确实)去Bar的mod,而不是Foo的. 因为这是真的,你无法按照你所展示的方式对其进行优化. 子类的合约是,当超类在自身上调用方法时,如果该方法被重写,则它将是要调用的子类的方法. 将方法声明为private,使其成为final或类 – 甚至创建递归函数而不是方法,所有这些都确保您不必去子类实现. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |