scala并不支持一般的for循环,取而代之的是for comprehesion。scala通过丰富
的for comprehesion特性支持各种循环结构。
要使一个类支持for comprehesion很简单,不需要继承任何trait,相应的实现
map, filter, flatMap, foreach四个方法中的一个或多个即可。下面针对每种
语法解释一下。
scala 伪代码
- // 语法形式
- for( val p <- e ) yield ee
- // 对应的函数调用 -- map
- e.map( p => ee )
-
- // 语法形式
- for( val p <- e ) ee
- // 对应的函数调用 -- foreach
- e.foreach { p => ee }
-
- // 语法形式
- for( val p <- e; val pp <- ee ) yield eee
- // 对应的函数调用 -- flatMap
- e.flatMap( p => for(pp <- ee ) yield eee )
-
- // 语法形式
- for( val p <- e; val pp <- ee ) eee
- // 对应的函数调用 -- foreach
- e.foreach( p => for( pp <- ee ) eee )
-
- // 语法形式
- for ( val p <- e ) if g ...
- // 对应的函数调用 -- filter
- p <- e.filter( ... => g )
也就是说,任何一个类,只要实现了map方法(参数为一个函数),就可以使用 for (val v < - new class) yield v 的语法。如果再实现了filter方法,就可以使用 for(val v < - obj if guard) yield v 的语法,如果实现了flatMap方法,就可以使用复合的 for(val v1< -o1; val v2< -o2) yield o1 op o2这样的语法,如果实现了foreach方法,可以实现 for(val v< -obj){f} 的语法。
scala对for comprehension的支持是通过在编译期检查类的方法增加的,不需要象java那样显示地从Iterable方法派生,而且4个函数之中可以根据需要来实现,要灵活地多。
举几个简单的例子对比一下
scala 代码
- class ForIterClass {
- def map(f: int => int): List[int] = List( 1, 2, 3 )
- def foreach(f: int => Unit) = println("hello foreach")
- }
- for( val p <- new ForIterClass) yield p
- // 等价于
- (new ForIterClass) map (p => p)
- for( val fc <- new ForIterClass ) println(fc)
- // 等价于
- (new ForIterClass) foreach (fc => println("hello foreach"))
- for { i <1 until n
- j <1 until i
- if isPrime(i+j)
- } yield (i, j)
- // 等价于
- (1 until n)
- .flatMap {
- case i => (1 until i)
- .filter { j => isPrime(i+j) }
- .map { case j => (i, j) } }