Scala:使用 for-yield 表达式打印乘法表

在《Programming in Scala》中作者说,“Scala 中的 for 表达式对于迭代就像一把瑞士军刀”。可见,for 表达式的使用在 Scala 中出于多么重要的位置。我们可以使用for 表达式来简洁地完成迭代枚举的功能。

与 Java 等不同的是,Scala 中有个生成器(generator)的概念,它的语法是 1 to 10 或者 1 until 10 ,前者代表从 1 到 10 进行迭代,而后者则表示从 1 到 9 进行迭代,也就是常说的偏差1(off-by-one)这个差别。你可以在 Scala 自带的解释器中输入 1 to 10 ,看看结果是什么。如下:

  
  
  
  
  1. scala> 1 to 10  
  2. res6: scala.collection.immutable.Range.Inclusive with scala.collection.immutable  
  3. .Range.ByOne = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)  
  4.  
  5. scala> 1 until 10  
  6. res7: scala.collection.immutable.Range with scala.collection.immutable.Range.ByO  
  7. ne = Range(1, 2, 3, 4, 5, 6, 7, 8, 9

由于 Scala 具有很多函数式编程的风格,它的许多控制结构都可以具有返回值,例如 if 语句,此时 Scala 中称为 if 表达式。同样,使用 for 表达式也可以具有返回值,这让我们看起来就像是一个有返回值的函数一样。不过想要达到这个目的,需要使用 yield 关键字,它用于指明在 for 迭代过程中生成一个集合并保存起来,它的语法是:

for {子句} yield {循环体}

尝试用 for – yield 表达式打印一个九九乘法表,代码如下: 

  
  
  
  
  1. def makeTable() = {  
  2.     // 先用 to  
  3.     val table = for(row <- 1 to 9yield {        
  4.         // 再用 until  
  5.         for(col <- 1 until 10yield {  
  6.             val line = (row * col).toString  
  7.             // 数好空格数  
  8.             val spaces = " " * (4 - line.length)  
  9.             (line + spaces).mkString  
  10.         }  
  11.     }  
  12.     // 换行  
  13.     table.mkString("\n")  

在控制台执行这个脚本,结果如下:

image

呼…打印出来的结果有点让人失望,显然 for-yield 表达式返回了 Vector 对象,这不是我想要的。不过我还搞不清楚里面的问题到底是什么,先放着吧。

下面是我修改过的书中的代码: 

  
  
  
  
  1. def makeRow(row: Int) =   
  2.     for(col <- 1 until 10) yield {  
  3.         val line = (row * col).toString  
  4.         val spaces = " " * (4 - line.length)  
  5.         line + spaces  
  6.     }  
  7.  
  8. def multiTable() = {  
  9.     val table =   
  10.         for(row <- 1 until 10)  
  11.             yield makeRow(row).mkString  
  12.     table.mkString("\n")  
  13. }  
  14. println(multiTable()) 

此时的打印结果如下:

image

你可能感兴趣的:(scala,职场,休闲,for表达式,yield关键字)