原创转载请注明出处: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编程思想