想象一下InputStream的以下变化:
trait FutureInputStream {
//read bytes asynchronously. Empty array means EOF
def read(): Future[Array[Byte]]
}
问题是如何为此类流编写discardAll函数?这是我的解决方案:
//function that discards all input and returns Future completed on EOF
def discardAll(is: FutureInputStream): Future[Unit] = {
val f = is.read()
f.flatMap {
case v if v.length == 0 =>
Future successful Unit
case _ =>
discardAll(is)
}
}
此代码的明显问题是不可优化的递归:它将很快用完堆栈。有更有效的解决方案吗?
您的解决方案没有错。的调用discardAll(is)
是异步完成的。它不会与上一次调用在同一堆栈帧中发生,因此不会有堆栈溢出。
您可以看到天真的实现会发生什么:
trait FutureInputStream {
var count = 0
def read(): Future[Array[Byte]] = {
if(count < 100000) {
count += 1
Future(Array(1))
} else
Future(Array())
}
}
如果您要discardAll
提供上述实例,则可以。
scala> val is = new FutureInputStream{}
is: FutureInputStream = $anon$1@255d542f
scala> discardAll(is).onComplete { println }
Success(())
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句