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

Scala newbie:递归和stackoverflow错误

发布时间:2020-12-16 18:58:39 所属栏目:安全 来源:网络整理
导读:作为 Scala新手,我正在阅读书籍文档,并尝试解决 http://aperiodic.net/phil/scala/s-99/发现的问题.似乎正确的Scala代码基于不可变值(val)和递归而不是循环和变量,以使并行性更安全并避免使用锁. 例如,运动P22(http://aperiodic.net/phil/scala/s-99/p22.sca
作为 Scala新手,我正在阅读书籍文档,并尝试解决 http://aperiodic.net/phil/scala/s-99/发现的问题.似乎正确的Scala代码基于不可变值(val)和递归而不是循环和变量,以使并行性更安全并避免使用锁.

例如,运动P22(http://aperiodic.net/phil/scala/s-99/p22.scala)的一个可能的解决方案是:

// Recursive.
def rangeRecursive(start: Int,end: Int): List[Int] =
if (end < start) Nil
else start :: rangeRecursive(start + 1,end)

当然,这个代码很紧凑,看起来很聪明,但是当然,如??果递归次数很高,那么你会遇到一个StackOverflow错误(例如,没有JVM调优的rangeRecusrsive(1,10000)).如果您查看内置List.range的源码(https://github.com/scala/scala/blob/v2.9.2/src/library/scala/collection/immutable/List.scala#L1),您会看到使用循环和变量.

我的问题是如何管理Scala学习内容的影响,促进vals和递归知道这样的代码可以由于递归的次数而中断?

解决方法

Scala的好处是,你可以轻松地进入它.从开始,您可以编写循环,并且随着语言越来越舒服,就可以进行更多的递归操作.您不能使用更纯粹的功能语言(如Clojure或Haskell)来执行此操作.换句话说,你可以很好地享受不变性和价值,随后再递交.

当您开始递归时,您应该查找尾部调用递归.如果递归调用是函数中的最后一个调用,则Scala编译器会将其优化为字节码循环.这样,你不会得到StackOverflowErrors.此外,如果将@tailrec注释添加到递归函数中,则编译器会警告您,如果您的函数不是尾调用递归.

例如,您的问题中的函数不是尾调用递归.看起来像rangeRecursive的调用是函数中的最后一个,但是当这个调用返回时,它仍然需要将start添加到调用的结果.因此,它不能是尾调用递归:当调用返回时,它仍然需要工作.

(编辑:李大同)

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

    推荐文章
      热点阅读