加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 生成器/块到迭代器/流转换

发布时间:2020-12-16 09:11:10 所属栏目:安全 来源:网络整理
导读:基本上我想转换这个: def data(block: T = Unit) 到一个流(dataToStream是一个假设的功能,做这个转换): val dataStream: Stream[T] = dataToStream(data) 我想这个问题可以通过延续来解决: // let's assume that we don't know how data is implemented//
基本上我想转换这个:

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”.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读