Scala 带有尾部递归的java.lang.OutOfMemoryError

Scala 带有尾部递归的java.lang.OutOfMemoryError,scala,tail-recursion,Scala,Tail Recursion,为什么我会得到java.lang.OutOfMemoryError:java堆空间,当我用像2000这样的大数字调用第一个函数时,第二个实现没有得到错误 两者不都保留相同的内存量吗 object TailRecursion extends App{ @tailrec def repeatString (str: String, n:Integer ): String = { if (n == 0) "" else if (n == 1) str else rep

为什么我会得到java.lang.OutOfMemoryError:java堆空间,当我用像2000这样的大数字调用第一个函数时,第二个实现没有得到错误

两者不都保留相同的内存量吗

object TailRecursion extends App{

  @tailrec
  def repeatString (str: String, n:Integer ): String = {
    if (n == 0) ""
    else if (n == 1) str
    else repeatString(str+str, n-1)
  }

  @tailrec
  def repeatString(str:String, n:Integer, accumulator:String):String ={
    if(n==0) accumulator
    else repeatString(str, n-1, str+accumulator)
  }

  println(repeatString("teste", 0))
  println(repeatString("teste", 1))
  println(repeatString("teste", 2))
  println(repeatString("teste", 2000))
}

不可以。两者都不会保留相同的内存量

让我们尝试使用Scala中的for表达式执行带有
OutOfMemory
错误的操作。它将大致转换为以下代码:

def repeatStringLoop(string: String, n: Integer): String = {
  var resultString = string
  if (n == 0) ""
  else if (n == 1) string
  else {
    for (i <- 0 until n) {
      resultString = resultString.concat(resultString)
    }    
    resultString
  }
}
def repeatStringLoop(string:string,n:Integer):string={
var resultString=string
如果(n==0)”
如果(n==1)字符串
否则{

对于(iNo)。两者不会保留相同的内存量

让我们尝试使用Scala中的for表达式执行带有
OutOfMemory
错误的操作。它将大致转换为以下代码:

def repeatStringLoop(string: String, n: Integer): String = {
  var resultString = string
  if (n == 0) ""
  else if (n == 1) string
  else {
    for (i <- 0 until n) {
      resultString = resultString.concat(resultString)
    }    
    resultString
  }
}
def repeatStringLoop(string:string,n:Integer):string={
var resultString=string
如果(n==0)”
如果(n==1)字符串
否则{

对于(i)对于构建大型字符串,请使用StringBuilder(和append,而不是prepend).-顺便说一句,这两个函数是不等价的。JVM也没有尾部调用优化。Clojure为此构建了很多防护措施,但我对Scala中的可用功能不是很有信心。总之,在任何基于JVM的系统中,在尾部rec调用中,您必须非常小心language@sinanspd不是
@tailrec
阻止代码from编译,如果剪下的不转换为尾部递归实现?是的,第一个与第二个不同,第一个连接字符串^1999,这就是内存不足的原因。第二个连接str*2000Try
println(repeatString(“teste”,5))
并比较结果。
repeatString()
#1正在生成一个更大的结果字符串。要生成大字符串,请使用StringBuilder(和append,而不是prepend).-顺便说一句,这两个函数是不等价的。JVM也没有尾部调用优化。Clojure为此构建了很多防护措施,但我对Scala中的可用功能不是很有信心。总之,在任何基于JVM的系统中,在尾部rec调用中,您必须非常小心language@sinanspd不是
@tailrec
阻止代码from编译,如果剪下的不转换为尾部递归实现?是的,第一个与第二个不同,第一个连接字符串^1999,这就是内存不足的原因。第二个连接str*2000Try
println(repeatString(“teste”,5))
并比较结果。
repeatString()
#1正在构建一个更大的结果字符串。