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

scala – 为什么函数尾不是递归的?

发布时间:2020-12-16 18:23:14 所属栏目:安全 来源:网络整理
导读:我正在阅读M. Odersky的 Scala编程,他说 Functions like approximate,which call themselves as their last action,are called tail recursive. 所以,我试过这个: object Main extends App { implicit val mc = new MyClass(8) val ti = new TestImplct ti.
我正在阅读M. Odersky的 Scala编程,他说

Functions like approximate,which call themselves as their last
action,are called tail recursive.

所以,我试过这个:

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)

IDEONE DEMO

但它会生成以下堆栈跟踪

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)

这意味着它为每个递归调用生成一个新的堆栈帧.但最后一步是呼唤自己.什么是错的,如何让它尾递归?

为什么编译器不进行尾调用优化?

解决方法

您可以尝试使用@tailrec注释标记方法.如果你这样做,编译将失败,并将告诉你为什么编译器无法优化它为尾递归:

Main.scala:12: error: could not optimize @tailrec annotated method test: it is neither private nor final so can be overridden

实际上,如果你将方法设为最终,它会按预期工作.

(编辑:李大同)

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

    推荐文章
      热点阅读