Scala StackOverflowError,而Java可以处理它

Dha*_*amy 5 java scala

我倾向于在S​​cala中编程并遇到这个问题,其中Scala代码抛出StackOverflowErorr,而Java中的类似实现可以在抛出相同的错误之前更多一点

  def recursiveSum(args: Int*): Int = {
    if (args.length == 0) 0
    else
      args.head + recursiveSum(args.tail: _*)

  }                                               

  recursiveSum(5000 to 15000: _*)  
Run Code Online (Sandbox Code Playgroud)

我得到的错误是

    java.lang.StackOverflowError
//|     at scala.collection.Parallelizable$class.$init$(Parallelizable.scala:20)
//|     at scala.collection.AbstractTraversable.<init>(Traversable.scala:105)
//|     at scala.collection.AbstractIterable.<init>(Iterable.scala:54)
//|     at scala.collection.AbstractSeq.<init>(Seq.scala:40)
//|     at scala.collection.immutable.Range.<init>(Range.scala:44)
//|     at scala.collection.immutable.Range$Inclusive.<init>(Range.scala:330)
//|     at scala.collection.immutable.Range$Inclusive.copy(Range.scala:333)
//|     at scala.collection.immutable.Range.drop(Range.scala:170)
//|     at scala.collection.immutable.Range.tail(Range.scala:196)
//|     at scala.collection.immutable.Range.tail(Range.scala:44)
//|     at Loops$$anonfun$main$1.recursiveSum$1(Loops.scala:11)
//|     at Loops$$anonfun$main$1.recursiveSum$1(Loops.scala:11)
//|     at Loops$$anonfun$main$1.recursiveSum$1(Loops.scala:11)
//|     at Loops$$anonfun$main$1.recursiveSum$1(Loops.scala:11)
//|     at Loops$$anonfun$m
//| Output exceeds cutoff limit.
Run Code Online (Sandbox Code Playgroud)

java代码是

static int recursiveSum(int... arg) {
        if (arg.length == 0)
            return 0;
        else
            return arg[0] + recursiveSum(Arrays.copyOfRange(arg, 1, arg.length));
    }

    public static void main(String[] args) {
        System.out.println(recursiveSum(range(5000, 15000)));
    }

    private static int[] range(int i, int j) {
        int list[] = new int[j - i + 1];
        int idx = 0;
        for (int s = i; s <= j; s++)
            list[idx++] = s;
        return list;
    }
Run Code Online (Sandbox Code Playgroud)

为什么Scala的尾递归优化没有帮助?Java如何处理(Java无法处理超过15000个16000)?

它们在台式机上以相同的eclipse运行,默认堆栈大小为java 7.

Tod*_*odd 7

这不是尾递归.为了使函数成为尾递归,函数中的最后一个语句(尾部)需要是递归调用.在你的情况下,它可能看起来像,但如果你用注释注释你的函数@tailrec,你会发现它不是.实际上,你的最后一个语句是一个补充,而不是递归调用.

如果你重写你的函数使用累加器,你将能够做一个尾递归版本...

def recursiveSum(args: Int*): Int = {
    @tailrec
    def sumAccumulator(sum: Int, args: Int*): Int = {
        if(args.length == 0) sum
        else sumAccumulator(sum + args.head, args.tail: _*)
    }
    sumAccumulator(0, args: _*)
}

recursiveSum(5000 to 15000: _*)
Run Code Online (Sandbox Code Playgroud)