加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala和尾递归

发布时间:2020-12-16 18:13:54 所属栏目:安全 来源:网络整理
导读:Stack Overflow上有各种答案,它解释了 Scala中尾递归的可能条件.我理解了局限性以及如何以及在哪里可以利用尾递归.我不理解的部分是为什么存在对私有或最终方法的限制. 我还没有研究过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中,mod函数在编译期间被传送到mod-non-recursive,因此Foo实际上没有一个mod方法来覆盖.

解决方法

我刚刚回答了这个问题,但让我们举个例子.假设您定义了类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或类 – 甚至创建递归函数而不是方法,所有这些都确保您不必去子类实现.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读