用于理解的 Scala
推导具有for (enumerators) yield e
的结构,其中 enumerators 是指以分号分隔的枚举器列表。枚举器要么是一个引入新变量的生成器,要么是一个过滤器。推导式计算枚举器生成的每个绑定的主体e并返回这些值的序列。
这些定义将我们引向生成器、过滤器和定义的理解思想。用于理解的 Scala 将包含以下 3 个表达式:
- 发电机
- 过滤器
- 定义
句法:
for {
b Generators -Generators have below form:pattern For example b In this expression the value b iterates over all of the elements contained in books.Below are two more things about generators -Each for comprehension begins with a generator.for comprehensions will be multiple generators.Definitions -For comprehension definitions have below syntax:pattern = expressionFor example n = b.name the variable n is bound to the value b.name. That statement has a similar result as writing this code outside of a for comprehension. val n = b.nameFilters -For comprehension filters have below form:if (expression)Expression have the type Boolean. Filters drop all elements from the iteration that which expression returns false, as like given code. For example if (n startsWith "Ca") any value n that does not start with the string Ca will be dropped during the iteration process.Let's discuss some examples.Example #1: With yield// Scala program of for comprehensions // Creating object object Geeks { // Main method def main(args: Array[String]) { // Creating case class case class Language(name: String, article: Int) val LanguageBase = List(Language("Scala", 26), Language("Csharp", 32), Language("Perl", 42), Language("Java", 22)) // Applying for comprehensions // Generator // Definition val MoreThanTwenty = for (language <- LanguageBase if (language.article >=20 && language.article < 30))// Filters // i.e. add this to a list yield language.name // Print more than twenty MoreThanTwenty.foreach(name => println(name)) } } Output :Scala
JavaIn above example, the for loop used with a yield statement actually creates a List. Because we said yield language.name, it’s a List[String]. language is our generator and if (language.article >=20 && language.article < 30) could be a guard that filters out article those don't seem to be in between 20 to 30. Example #2: Without yieldWe can omit yield in comprehension. In that case, comprehension will return Unit. This can be helpful just in case we would like to perform side-effects. Here’s a program like the above one, without using yield.// Scala program to print Hello, Geeks! // by using object-oriented approach // creating object object Geeks { // Main method def main(args: Array[String]) { def check(a: Int) = for (i <- 0 until 4; j <- 0 until 4 if i * j >= a) println(s"($i, $j)") check(4)} } Output:(2, 2)
(2, 3)
(3, 2)
(3, 3)In above example, a = 4. In the first iteration, i = 0 and j = 0 so i * j is not greater than equal to a and therefore nothing is yielded. j gets incremented 3 more times before i gets incremented to 1.