原创转载请注明出处:http://agilestyle.iteye.com/blog/2333647
for和if的组合称为for推导,简称为推导。先看一个简单的例子:
package org.fool.scala.comprehension
object ComprehensionTest extends App {
def evenGT5(v: Vector[Int]): Vector[Int] = {
// 'var' so we can reassign 'result'
var result = Vector[Int]()
for {
n <- v
if n > 5
if n % 2 == 0
} result = result :+ n
result
}
val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
println(evenGT5(v))
}
Note:
result为var而不是val
Vector有一个操作符“:+”,它会接受一个Vector(但是不会修改它),并将操作符右边的元素与其组合起来,以此创建一个新的Vector。
Console Output

有一种将result用作val(而不是var)的方式:by building result "in place" rather than creating it piece-by-piece。为了实现这个目的,可是使用Scala的yield关键字。当你声明yield n时,它会将值n "yield up"出来,使其成为result的一部分。
package org.fool.scala.comprehension
object Yielding extends App {
def yielding(v: Vector[Int]): Vector[Int] = {
val result = for {
n <- v
if n < 10
if n % 2 != 0
} yield n
result
}
val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
println(yielding(v))
}
Console Output

接下来在推导内部定义值,并且不存储和返回中间结果result
package org.fool.scala.comprehension
object Yielding2 extends App {
def yielding2(v: Vector[Int]): Vector[Int] = {
for {
n <- v
if n < 10
isOdd = (n % 2 != 0)
if (isOdd)
} yield n
}
val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
println(yielding2(v))
}
Console Output

与其他任何表达式一样,yield表达式也可以组合
package org.fool.scala.comprehension
object Yielding3 extends App {
def yielding3(v: Vector[Int]): Vector[Int] = {
for {
n <- v
if n < 10
isOdd = (n % 2 != 0)
if (isOdd)
} yield {
// only inside the comprehension can you get away without declaring val or var for new identifiers.
val u = n * 10
u + 2
}
}
val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
println(yielding3(v))
}
Note:
只有在推导内部才能不为新标识符声明val或var
Console Output

可以将一个推导只与一个yield表达式相关联,并且不能将yield表达式置于推导体之前。但是推导可以嵌套:
package org.fool.scala.comprehension
object Yielding4 extends App {
def yielding4(v: Vector[Int]) = {
for {
n <- v
if n < 10
isOdd = (n % 2 != 0)
if (isOdd)
} yield {
for (u <- Range(0, n))
yield u
}
}
val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
println(yielding4(v))
}
Console Output

参考资料:
Scala编程思想
本文介绍了Scala中for与if组合使用的方法,包括如何通过yield关键字简化代码,以及如何在推导内部定义值而不存储中间结果。此外还展示了推导可以嵌套使用的特性。
1038

被折叠的 条评论
为什么被折叠?



