我将从引用开始Scala编程。 “每个表达式都可以用三个高阶函数map,flatMap和filter来表示。这部分描述了Scala编译器也使用的翻译方案。“ http://www.artima.com/pins1ed/for-expressions-revisited.html#23.4
因此,您注意到for-loops的原因并不多,因为它们在技术上并不需要,而且对于表达式你看到的仅仅是语法糖,编译器会翻译成一些等价的语法。上面的链接中列出了将表达式翻译成map/flatMap/filter表达式的规则:
一般来说,在函数式编程中,没有索引变量可以进行变异,这意味着通常会大量使用函数调用(通常以递归的形式),比如列表折叠而不是一段时间或循环。
对于使用列表折叠来代替while/for循环的一个很好的例子,我推荐Tony Morris的“向你自己解释列表折叠”。 https://vimeo.com/64673035
如果一个函数是尾递归的(用@tailrec表示),那么它可以进行优化,以避免在递归函数中高度使用堆栈。在这种情况下,编译器可以将尾递归函数转换为“while循环等效”。
要回答问题1的第二部分,有些情况下可以说一个for表达式更清楚(尽管肯定也有相反的情况。)一个这样的例子在Coursera.org课程“Scala的函数编程”由马丁·奥德斯基博士:
for {
i <- 1 until n
j <- 1 until i
if isPrime(i + j)
} yield (i, j)
可以说是比
(1 until n).flatMap(i =>
(1 until i).withFilter(j => isPrime(i + j))
.map(j => (i, j)))
更清晰欲了解更多信息,请查阅马丁·奥德斯基博士的“函数式编程使用Scala”当然在Coursera.org上。第6.5讲“For的翻译”特别详细讨论了这一点。
而且,作为一个快速侧面说明,在您的例子中,你使用
mapper.map(x => println(x))
人们普遍所接受使用的foreach在这种情况下,因为你有副作用的意图。此外,还有手短
mapper.foreach(println)
至于第二个问题,这是更好地使用地图功能替代循环(尤其是当有突变的循环),因为地图是一个功能,它可以由。而且,一旦熟悉并习惯使用地图,就很容易推理。
对于您给(打印输出)的例子,您不会使用map,但会使用iter。当你将一个集合元素从类型A转换为类型B时,映射就是你所使用的。 – BitTickler
请注意,Scala中的'for'循环被编译器转换为包括'map'和'flatMap'在内的操作 - 参见[this question]( http://docs.scala-lang.org/tutorials/FAQ/yield.html),例如 – DNA
@DNA所以for循环只是一个合成糖,它将被编译器转换为map和flatMap。 – Knight71