Scala未来合并

谢尔盖·阿拉维(Sergey Alaev)

想象一下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)
  }
}

此代码的明显问题是不可优化的递归:它将很快用完堆栈。有更有效的解决方案吗?

迈克尔·扎亚克(Michael Zajac)

您的解决方案没有错。的调用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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章