在trait中定义的Scala尾递归流处理函数保存流头的引用 [英] Scala tail-recursive Stream processor function defined in trait holds reference to stream-head
问题描述
在以下情况中:
trait T {
@tailrec
def消费[A](as:Stream [A]):Unit = {
if(as.isEmpty)()
else consume(as.tail)
}
}
object O extends T
调用 O.consume(范围(1,N).toStream)
与 N
足够大,程序将耗尽内存,或至少会消耗O(N )而不是所需的O(1)。
为特征生成尾递归方法。特质扩展器中的方法入口(这里 O
)将调用转发给特征的方法,但是在这样做的时候,它会保持对特征头部的引用Stream。
因此这个方法是尾递归的,但是内存仍然不能被释放。补救措施:不要直接在对象中定义特性中的Stream函数。
另一个选择是scalaz的 EphemeralStream
,和尾巴,并根据需要重新计算它们。
In the following situation
trait T {
@tailrec
def consume[A](as: Stream[A]): Unit = {
if (as.isEmpty) ()
else consume(as.tail)
}
}
object O extends T
calling O.consume(Range(1, N).toStream)
with N
big enough, the program will run out of memory, or at least will consume O(N) instead of the needed O(1).
The tail-recursive method is generated for the trait. The method entry in the extender of the trait (here O
) forwards the call to the method of the trait, but while doing so, it keeps a reference to the head of the Stream.
Thus the method is tail-recursive, but memory still can't be released. Remedy: Don't define Stream functions in traits, just directly in objects.
An alternative is scalaz's EphemeralStream
, which holds weak references to the stream head and tail, and recomputes them on demand.
这篇关于在trait中定义的Scala尾递归流处理函数保存流头的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!