Kig*_*gyo 78 scala lazy-evaluation for-comprehension scala-collections
在使用map,flatmap等函数后,使用withFilter而不是过滤器总是更高效吗?
为什么只支持map,flatmap和foreach?(预期的功能如forall/exists)
Sha*_*nds 116
来自Scala文档:
注:之间的区别
c filter p,并c withFilter p为前者创造一个新的集合,而后者只限制后续的域map,flatMap,foreach,和withFilter操作.
因此,filter将采用原始集合并生成新集合,但withFilter非严格(即懒惰地)将未经过滤的值传递到以后的map/ flatMap/ withFilter调用,从而节省了第二次通过(已过滤)集合.因此,当传递给这些后续方法调用时,它将更有效.
事实上,它withFilter是专门为处理这些方法的链而设计的,这就是理解被去除的东西.此处不需要其他方法(例如forall/ exists),因此它们尚未添加到FilterMonadic返回类型中withFilter.
除了Shadowlands的优秀答案之外,我想带一个直观的例子来说明filter和之间的区别withFilter.
我们考虑以下代码
val list = List(1, 2, 3)
var go = true
val result = for(i <- list; if(go)) yield {
go = false
i
}
Run Code Online (Sandbox Code Playgroud)
大多数人都希望result等于List(1).自Scala 2.8以来就是这种情况,因为for-comprehension被翻译成了
val result = list withFilter {
case i => go
} map {
case i => {
go = false
i
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,转换将条件转换为调用withFilter.先前的Scala 2.8,for-comprehension被翻译成如下内容:
val r2 = list filter {
case i => go
} map {
case i => {
go = false
i
}
}
Run Code Online (Sandbox Code Playgroud)
使用时filter,价值result会大不相同:List(1, 2, 3).我们制作go标志的事实false对过滤器没有影响,因为过滤器已经完成.同样,在Scala 2.8中,使用这个问题解决了这个问题withFilter.当withFilter被使用时,条件被评估每一个元件被一个内部访问的时间map的方法.
参考: - p.120,Scala在行动(涵盖Scala 2.10),Manning出版物,Milanjan Raychaudhuri - Odersky关于理解翻译的想法