scala – 生成器/块到迭代器/流转换
基本上我想转换这个:
def data(block: T => Unit) 到一个流(dataToStream是一个假设的功能,做这个转换): val dataStream: Stream[T] = dataToStream(data) 我想这个问题可以通过延续来解决: // let's assume that we don't know how data is implemented // we just know that it generates integers def data(block: Int => Unit) { for (i <- 0 to 10) block(i) } // here we can print all data integers data { i => println(i) } // >> but what we really want is to convert data to the stream << // very dumb solution is to collect all data into a list var dataList = List[Int]() data { i => dataList = i::dataList } // and make a stream from it dataList.toStream // but we want to make a lazy,CPU and memory efficient stream or iterator from data val dataStream: Stream[Int] = dataToStream(data) dataStream.foreach { i => println(i) } // and here a black magic of continuations must be used // for me this magic is too hard to understand // Does anybody know how dataToStream function could look like? 谢谢,Dawid 解决方法
EDITED:修改了示例,以显示遍历视图的懒惰
scala> def data(f : Int => Unit) = for(i <- 1 to 10) { | println("Generating " + i) | f(i) | } data: (f: (Int) => Unit)Unit scala> def toTraversable[T]( func : (T => Unit) => Unit) = new Traversable[T] { | def foreach[X]( f : T => X) = func(f(_) : Unit) | } toTraversable: [T](func: ((T) => Unit) => Unit)java.lang.Object with Traversable[T] toTraversable方法将您的数据功能转换为可移植的集合.这本身就没什么大不了的,但是你可以将它转换成一个懒惰的TraversableView.以下是一个例子: scala> toTraversable(data).view.take(3).sum Generating 1 Generating 2 Generating 3 Generating 4 res1: Int = 6 采取方法的不幸性质在于,它必须超过生成的最后一个值才能正常工作,但它会提前终止.如果没有“.view”调用,上述代码看起来一样.但是,这是一个更引人注目的例子: scala> toTraversable(data).view.take(2).foreach(println) Generating 1 1 Generating 2 2 Generating 3 所以总而言之,我相信你正在寻找的集合是TraversableView,这是最简单的创建一个可视化,然后调用“视图”的视图.如果您真的想要Stream类型,那么这个方法可以在2.8.0.final中工作,并且将会创建一个没有线程的“Stream” scala> def dataToStream( data : (Int => Unit) => Unit) = { | val x = new Traversable[Int] { | def foreach[U](f : Int => U) = { | data( f(_) : Unit) | } | } | x.view.toList.toStream | } dataToStream: (data: ((Int) => Unit) => Unit)scala.collection.immutable.Stream[Int] scala> dataToStream(data) res8: scala.collection.immutable.Stream[Int] = Stream(0,?) 这种方法的不幸之处在于,它将在生成流之前遍历整个遍历.这也意味着所有的值都需要在内存中进行缓冲.唯一的选择是诉诸线程. 另外:这是一个激励的原因,喜欢Traversables作为从scalax.io.File方法的直接返回:“lines”“chars”和“bytes”. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |