【问题标题】:Can Scala do tail recursion for different methods that call each other?Scala 可以对相互调用的不同方法进行尾递归吗?
【发布时间】:2012-03-15 19:19:16
【问题描述】:

我使用分层数据结构做一些事情,并且我设计了一组方法来使用间接递归对其进行遍历/分析,如下所述。

有a、b、c 和d 方法,它们都具有Unit 返回类型。首先调用方法a。根据数据,它会做一些事情,然后停止或调用b/c/d 之一。 b、c 和 d 中的每一个都是一样的——每个方法都可以停止或调用其他 3 个方法中的任何一个。所以调用了哪些方法,它们的执行顺序直到运行时才知道,并且递归并不直接明显,因为没有方法直接调用自己(不用担心,每个方法都会被注释以描述循环/递归的性质电话)。

对a、b、c 或d 的每次额外调用是每个方法中执行的最后一件事,但它并不是每个方法的最后一个语句;将有一个 if 或 case 语句来控制将调用哪个语句。

在没有方法直接调用自身的情况下,Scala 编译器是否能够分析这个多层调用链并为其实现尾递归?

【问题讨论】:

    标签: scala recursion tail-recursion tail-call-optimization


    【解决方案1】:

    不,Scala 无法执行那种尾调用优化; JVM 并没有真正让这成为可能(或者至少不容易)。

    但是,您可以通过编写一个函数来自己模仿它,该函数可以根据参数采用四种不同的路径。 (如果编译器要帮助你,它必须做这样的事情。)

    【讨论】:

    • 沿着这些思路,我正在考虑让每个方法返回下一个要执行的方法(如函数式编程),而不是直接调用下一个方法并返回Unit。然后更高级别的方法将执行下一个方法,因此可以完全避免递归。
    • @Gigatron - 这几乎就是scala.util.control.TailCalls 所做的。
    【解决方案2】:

    尽管编译器无法自动为您执行此操作,但您的用例应该可以使用 scala.util.control.TailCalls。

    虽然这不会很高效,如果你的调用只有 4 深,那可能不值得。

    【讨论】:

    • 它不仅仅是 4 层,它是任意数量的层。当 a 调用 b 时,b 可以调用 c 再次调用 a,然后调用 d 回调 a 以此类推。
    • 只有我一个人,还是你链接到的那个网站真的很难加载?
    猜你喜欢
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 2015-09-10
    相关资源
    最近更新 更多