优雅遍历Scala中的源代码

时间:2017-02-25 09:47:27

标签: scala iterator traversal

作为一名数据科学家,我经常使用以下模式进行数据提取(即数据库,文件读取等):

val source = open(sourceName)
var item = source.getNextItem()
while(item != null){
    processItem(item)
    item = source.getNextItem()
}
source.close

我的(当前)梦想是将这种冗长的内容包装成Scala对象“SourceTrav”,这将允许这种优雅:

SourceTrav(sourceName).foreach(item => processItem(item))

具有与上面相同的功能,但没有遇到StackOverflowError,就像Semantics of Scala Traversable, Iterable, Sequence, Stream and View?中的例子一样

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

如果Scala的标准库(例如scala.io.Source)不适合您的需求,您可以使用不同的IteratorStream伴随对象方法来包装手动迭代器遍历。

在这种情况下,例如,当您已有开源时,可以执行以下操作:

Iterator.continually(source.getNextItem()).takeWhile(_ != null).foreach(processItem)

如果您还想添加源的自动开启和关闭,请不要忘记添加try - finally或其他一些loan模式:

case class SourceTrav(sourceName: String) {
  def foreach(processItem: Item => Unit): Unit = {
    val source = open(sourceName)
    try {
      Iterator.continually(source.getNextItem()).takeWhile(_ != null).foreach(processItem)
    } finally {
      source.close()
    }
  }
}