Scala 带有尾部递归的java.lang.OutOfMemoryError
为什么我会得到java.lang.OutOfMemoryError:java堆空间,当我用像2000这样的大数字调用第一个函数时,第二个实现没有得到错误 两者不都保留相同的内存量吗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
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*2000Tryprintln(repeatString(“teste”,5))
并比较结果。repeatString()
#1正在生成一个更大的结果字符串。要生成大字符串,请使用StringBuilder(和append,而不是prepend).-顺便说一句,这两个函数是不等价的。JVM也没有尾部调用优化。Clojure为此构建了很多防护措施,但我对Scala中的可用功能不是很有信心。总之,在任何基于JVM的系统中,在尾部rec调用中,您必须非常小心language@sinanspd不是@tailrec
阻止代码from编译,如果剪下的不转换为尾部递归实现?是的,第一个与第二个不同,第一个连接字符串^1999,这就是内存不足的原因。第二个连接str*2000Tryprintln(repeatString(“teste”,5))
并比较结果。repeatString()
#1正在构建一个更大的结果字符串。