我看到了这个方法:
trait Compressioner {
def ioStream(is: InputStream, os: OutputStream, bufferSize: Int = 4096): Int = {
val buffer = new Array[Byte](bufferSize)
@tailrec
def doStream(total: Int): Int = {
val n = is.read(buffer)
if (n == -1) total
else {
os.write(buffer, 0, n)
doStream(total + n)
}
}
doStream(0)
}
所以我只想查看是否理解这一点。我们正在初始化字节数组(字节长度为8位,用于表示字符或字母),这是我们的缓冲区(临时存储,通常在内存中)。
什么是@符号?
然后我们从输入流中读取4096个字节(一次通常是4096个字符?)。如果没有任何内容,read
会返回-1,这是我们的最终条件。否则,我们读取我们读取的字节并将其写入输出流。这是正确的解释吗?我说的不准确吗?
答案 0 :(得分:0)
实际上尾递归与Scala无关。这是内存有效的递归,因为我们所做的,在计算结果时我们没有将前一个结果保留在递归堆栈中,而是我们将答案保留为函数参数,所以当从递归返回时我们不需要值我们以前计算过。这只是一种提高算法空间效率的方法。每个递归函数都可以写成尾递归函数,但是没有数学证明!
有关尾递归的更多信息,可以参考此链接。这更像是尾递归的算法解释。
例如
阶乘程序的正常递归函数。
def fact(n)={
If(n==0)
return 1
n*fact(n-1)
}
我们将会发生什么事情,直到n == 0 像这样。 事实(4)
4*fact(3)
3*fact(2)
2*fact(1)
1*fact(0) //it will return 1
但是在我们返回1之前,我们需要在内存中进行所有其他函数调用以最终计算阶乘。
尾递归函数
def factorial(n: Int): Int = {
@tailrec
def iter(x: Int, result: Int): Int =
if (x == 1) result
else iter(x - , result * x)
iter(n, 1)
}
fact(5)
在尾递归函数中,最后一次调用应该是函数调用,这是我们应该记住的事情。
https://www.google.co.in/amp/s/www.geeksforgeeks.org/tail-recursion/amp/
特别是Scala你可以参考这个。
https://alvinalexander.com/scala/fp-book/tail-recursive-algorithms