scala - 有没有办法关闭Scala编译器的尾递归优化?

标签 scala tail-recursion

由于某些特殊原因,我想在一个大程序中去除所有@tailrec 的影响,但不想手动这样做,编译时是否有任何可选参数可以关闭尾递归优化?我只想在代码中保留@tailrec,但不想检查它并在编译时进行尾递归优化。这可能吗?

最佳答案

您可以使用编译器的 -g:notailcalls 选项。

来自文档:

-g:{none,source,line,vars,notailcalls}

"none" generates no debugging info,

"source" generates only the source file attribute,

"line" generates source and line number information,

"vars" generates source, line number and local variable information,

"notailcalls" generates all of the above and will not perform tail call optimization.

请注意,如文档所述,这还将启用调试信息生成


一个例子:

import scala.annotation.tailrec

class A {

@tailrec
final def x(i: Int): Int = if(i == 0) {i;} else {x(i-1)}

}

javap -p -v A.class of x 当“正常”编译时:

public final int x(int);
    descriptor: (I)I
    flags: ACC_PUBLIC, ACC_FINAL
    Code:
      stack=2, locals=2, args_size=2
         0: iload_1
         1: iconst_0
         2: if_icmpne     7
         5: iload_1
         6: ireturn
         7: iload_1
         8: iconst_1
         9: isub
        10: istore_1
        11: goto          0

相同,当使用 -g:notailcalls 编译时:

public final int x(int);
    descriptor: (I)I
    flags: ACC_PUBLIC, ACC_FINAL
    Code:
      stack=3, locals=2, args_size=2
         0: iload_1
         1: iconst_0
         2: if_icmpne     9
         5: iload_1
         6: goto          16
         9: aload_0
        10: iload_1
        11: iconst_1
        12: isub
        13: invokevirtual #12                 // Method x:(I)I
        16: ireturn

重要的一点是位置 13 上的 invokevirtual


请注意,顺便说一句,jwvh 谨慎地纠正了您对 @tailrec 的解释 - 它实际上并没有切换尾部优化,它唯一做的就是通知编译器如果它不能插入尾调用优化,则失败,它无论如何都会尝试

关于scala - 有没有办法关闭Scala编译器的尾递归优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32324859/

相关文章:

postgresql - Slick:postgresql中用于扩展存储的列

.net - CLR .tail 指令是否禁用抢占式 GC?

recursion - F#:互递归数据结构的变态

recursion - 迭代过程与递归过程

Python 3.7 : How to avoid stackoverflow for this recursive approach?

regex - 斯卡拉。分割线正则表达式返回意外的空字符串

scala - Yarn 集群模式下 Spark 作业的 ClassNotFoundException

scala - 除了 Scala 之外,还有什么第二语言用于 LowLevel?

recursion - Racket :识别尾递归?

scala - 计算一行的秩