gpt4 book ai didi

scala - 我的 Scala 代码虽然通过了 @tailrec,但没有获得 TCO

转载 作者:行者123 更新时间:2023-12-04 17:26:30 24 4
gpt4 key购买 nike

我正在研究 scala TCO 并编写了以下代码

import scala.annotation.tailrec
final def tailReccursionEx(str:String):List[String]={

@tailrec
def doTailRecursionEx(str:String,pos:Int,accu:List[String]):List[String]={
if(pos==str.length) return accu
else{
doTailRecursionEx(str,pos+1,accu++accu.foldLeft(List[String](str(`pos`).toString)){
(l,ch)=>l:+ch+str(`pos`)})
}
}

doTailRecursionEx(str,0,List[String]())
}

我已经通过了@tailrec 测试,我相信我的函数是自递归尾调用。然而,当我查看 java 字节码时
javap -c -private RecursionEx\$\$anonfun\$doTailRecursionEx\$1\$1

我没有看到自递归函数的 TCO promise 的 goto。这是字节码。
public RecursionEx$$anonfun$doTailRecursionEx$1$1(java.lang.String, int);
Code:
0: aload_0
1: aload_1
2: putfield #35; //Field str$2:Ljava/lang/String;
5: aload_0
6: iload_2
7: putfield #41; //Field pos$1:I
10: aload_0
11: invokespecial #93; //Method scala/runtime/AbstractFunction2."<init>":()V
14: return

}

最佳答案

我认为你需要运行 javap在不同的生成类文件上。您目前正在检查的文件对应于您在 foldLeft 中使用的闭包.如果您尝试查看“RecursionEx$.class”文件,您应该会看到尾调用递归。当我编译代码时:

import scala.annotation.tailrec

object RecursionEx {
@tailrec
final def doTailRecursionEx(str: String, pos: Int, accu: List[String]): List[String] = {
if (pos == str.length) return accu
doTailRecursionEx(str, pos + 1 , accu ++ accu.foldLeft(List[String](str(`pos`).toString)) {
(l, ch) => l :+ ch + str(`pos`)
})
}
def main(args: Array[String]) {
doTailRecursionEx("mew",0,List[String]())
}
}

然后运行 ​​ javap -c -private RecursionEx$我看到相关代码部分的以下内容:
public final scala.collection.immutable.List doTailRecursionEx(java.lang.String, int, scala.collection.immutable.List);

Code:
0: iload_2
1: aload_1
2: invokevirtual #21; //Method java/lang/String.length:()I
5: if_icmpne 10
8: aload_3
9: areturn
10: iload_2
11: iconst_1
12: iadd
13: aload_3
14: aload_3
15: getstatic #26; //Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
18: getstatic #31; //Field scala/Predef$.MODULE$:Lscala/Predef$;
21: iconst_1
22: anewarray #17; //class java/lang/String
25: dup
26: iconst_0
27: getstatic #31; //Field scala/Predef$.MODULE$:Lscala/Predef$;
30: aload_1
31: invokevirtual #35; //Method scala/Predef$.augmentString:(Ljava/lang/String;)Lscala/collection/immutable/StringOps;
34: iload_2
35: invokeinterface #41, 2; //InterfaceMethod scala/collection/immutable/StringLike.apply:(I)C
40: invokestatic #47; //Method scala/runtime/BoxesRunTime.boxToCharacter:(C)Ljava/lang/Character;
43: invokevirtual #53; //Method java/lang/Object.toString:()Ljava/lang/String;
46: aastore
47: checkcast #55; //class "[Ljava/lang/Object;"
50: invokevirtual #59; //Method scala/Predef$.wrapRefArray:([Ljava/lang/Object;)Lscala/collection/mutable/WrappedArray;
53: invokevirtual #62; //Method scala/collection/immutable/List$.apply:(Lscala/collection/Seq;)Lscala/collection/immutable/List;
56: new #64; //class RecursionEx$$anonfun$doTailRecursionEx$1
59: dup
60: aload_1
61: iload_2
62: invokespecial #67; //Method RecursionEx$$anonfun$doTailRecursionEx$1."<init>":(Ljava/lang/String;I)V
65: invokeinterface #73, 3; //InterfaceMethod scala/collection/LinearSeqOptimized.foldLeft:(Ljava/lang/Object;Lscala/Function2;)Ljava/lang/Object;
70: checkcast #75; //class scala/collection/TraversableOnce
73: getstatic #26; //Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
76: invokevirtual #79; //Method scala/collection/immutable/List$.canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
79: invokevirtual #85; //Method scala/collection/immutable/List.$plus$plus:(Lscala/collection/TraversableOnce;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
82: checkcast #81; //class scala/collection/immutable/List
85: astore_3
86: istore_2
87: goto 0

goto最后,正如您所期望的那样。

关于scala - 我的 Scala 代码虽然通过了 @tailrec,但没有获得 TCO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8219054/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com