Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有多参数列表的Scala方法中的尾部递归性_Scala - Fatal编程技术网

具有多参数列表的Scala方法中的尾部递归性

具有多参数列表的Scala方法中的尾部递归性,scala,Scala,我有以下功能: @tailrec def samePrefix[A](length: Int)(a: Vector[A], b: Vector[A]): Boolean = { if(length<1) true else{ if(a(length-1)==b(length-1)) samePrefix(length-1)(a, b) else false } } 将首先从samePrefix(length-1)创建一个函数对象

我有以下功能:

  @tailrec
  def samePrefix[A](length: Int)(a: Vector[A], b: Vector[A]): Boolean = {
    if(length<1) true
    else{
      if(a(length-1)==b(length-1)) samePrefix(length-1)(a, b)
      else false
    }
  }
将首先从
samePrefix(length-1)
创建一个函数对象,然后对其应用
(a,b)
,或者如果它只是递归地调用我的方法tail。

让我们看看

$ scala
Welcome to Scala version 2.11.1
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.annotation._
import scala.annotation._

scala> @tailrec def curried(a: Int)(b: Int): Int = curried(a-1)(b-1)
curried: (a: Int)(b: Int)Int

scala> :javap curried
  ... irrelevant output removed ...       

  public int curried(int, int);
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=3, args_size=3
         0: iload_1       
         1: iconst_1      
         2: isub          
         3: iload_2       
         4: iconst_1      
         5: isub          
         6: istore_2      
         7: istore_1      
         8: goto          0

  ... irrelevant output removed ...
如您所见,字节码中没有递归调用。相反,有一条指示循环的
goto 0
指令。这意味着尾部调用优化已经发生

您还将注意到,在编译的字节码中,多个参数列表被压缩为单个参数列表,因此不涉及中间函数


EDIT:实际上,我们并不需要检查字节码来100%确定该方法是使用TCO编译的,因为
@tailrec
注释正是为了这个目的而存在的。换句话说,如果您在方法上放置
@tailrec
,并且它编译时没有错误,那么您可以100%确定它是使用TCO编译的。

谢谢。我想我应该开始学习如何解释Java字节码。
$ scala
Welcome to Scala version 2.11.1
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.annotation._
import scala.annotation._

scala> @tailrec def curried(a: Int)(b: Int): Int = curried(a-1)(b-1)
curried: (a: Int)(b: Int)Int

scala> :javap curried
  ... irrelevant output removed ...       

  public int curried(int, int);
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=3, args_size=3
         0: iload_1       
         1: iconst_1      
         2: isub          
         3: iload_2       
         4: iconst_1      
         5: isub          
         6: istore_2      
         7: istore_1      
         8: goto          0

  ... irrelevant output removed ...