Scala为了表达序列解析提供了一种轻量级的符号。解析式的形式如for (enumerators) yield e,其中enumerators是以分号分隔的枚举器列表。一个枚举器要么是产生新变量的生成器,要么是一个过滤器。解析式对于由枚举器生成的每一个绑定的主体e进行赋值,并且返回这些值的一个序列。
下面是示例:
1 | case class User(val name: String, val age: Int) |
这里的for循环使用了yield语句会生成一个List。因为这里的yield user.name是一个List[String]。user <- userBase是一个生成器,而if (user.age >=20 && user.age < 30)是一个守卫,用于过滤出20多岁的用户。
这里有一个更加复杂的例子,使用了2个生成器,用来计算出介于0到n-1之间所有可能的数值对,且它们的和等于给定的值v:
1 | def foo(n: Int, v: Int) = |
在这里n == 10,v == 10。在第一次迭代中,i == 0且j == 0则i + j != v,因而没有值生成。在i递增到1之前,j会递增9次。如果没有守卫条件,则会输出如下:
1 | (0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) (0, 9) (1, 1) ... |
注意,解析式并不局限于列表。所有支持withFilter、map和flatMap操作的数据类型都可以用于序列解析。
你可以在解析式中省略yield。那样的话,解析式会返回Unit。这点在你需要执行具有副作用的操作时比较有用。下面是一个和之前完全类似的程序,只不过没有使用yield:
1 | def foo(n: Int, v: Int) = |