我目前正在尝试学习Scala并强迫我尽可能使用函数式编程风格。
以下代码有一个我不理解的流程:
object Testing {
def XForm(i: Int) = {
println(i)
if (i < 3) "%d".format(i * i) else ""
}
def main(args: Array[String]) {
print(Range(0, 6).map(XForm).takeWhile(_.nonEmpty))
}
}
输出如下:
0
1
2
3
4
5
Vector(0, 1, 4)
为什么XForm
要求值4和5?我以为&#39;循环&#39;使用takeWhile(在比较过滤时)会在第一次出现错误时终止吗?
如何以不同的(功能风格)方式解决这个问题?
答案 0 :(得分:2)
map
上的Range
是严格的,因此会立即对其进行评估。也就是说,如果您删除了takeWhile
,那么在您到达takeWhile
之前,您会看到所有内容都会进行评估:
scala> Range(0, 6).map(XForm)
0
1
2
3
4
5
res1: scala.collection.immutable.IndexedSeq[String] = Vector(0, 1, 4, "", "", "")
您可以使用view
来解决此问题,这会懒惰地评估该集合。
scala> Range(0, 6).view.map(XForm).takeWhile(_.nonEmpty).force
0
1
2
3
res4: Seq[String] = Vector(0, 1, 4)