2011-11-21 12 views
5

मैं स्केला TCO में देख रहा हूँ और निम्नलिखित कोड लिखा हैमेरे स्केला कोड TCO'ed नहीं मिलता है, हालांकि यह @tailrec गुजरता

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 परीक्षण बीत चुके हैं और मेरा मानना ​​है कि मेरी समारोह है कि आत्म-पुनरावर्ती पूंछ कॉल। फिर भी, जब मैं

javap -c -private RecursionEx\$\$anonfun\$doTailRecursionEx\$1\$1 

साथ जावा बाइट कोड पर गौर मुझे नहीं देने का वादा किया गोटो TCO के लिए स्वयं पुनरावर्ती क्रिया के लिए दिख रहा है। बाइटकोड यहाँ है।

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 

} 

उत्तर

10

मैं आप एक अलग उत्पन्न वर्ग फ़ाइल पर javap चलाने की आवश्यकता है। वर्तमान में जिस फ़ाइल की आप जांच कर रहे हैं वह उस बंदरगाह से मेल खाती है जिसका उपयोग आप foldLeft के हिस्से के रूप में करते हैं। यदि आप "रिकर्सियनएक्स $। क्लास" फ़ाइल को देखने का प्रयास करते हैं तो आपको पूंछ कॉल रिकर्सन देखना चाहिए। जब मैं कोड संकलन:

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 साथ

, बस के रूप में आप उम्मीद करेंगे।