1. 程式人生 > >Scala之for迴圈

Scala之for迴圈

Scala沒有與for()迴圈直接對應的結構。如果你需要這樣的迴圈,有兩個選擇:一是使用while迴圈,而是使用如下for語句:

for (i <- 1 to n)
  r = r * i
說明:1 to n 這個呼叫返回數字1到數字n的Range(區間)。

to,until都表示範圍,二者有何區別?

to為包含上限的閉區間,如:1 to 3,Range為1,2,3;

until不包含上限,如:1 to 3, Range為1,2

在需要使用從0到n-1的區間時,可以使用until方法。

語法結構for (i <- 表示式)讓變數i遍歷<-右邊的表示式的所有值。至於這個遍歷具體如何執行,則取決於表示式的型別。對於Scala集合比如Range而言,這個迴圈會讓i依次取得區間中的每個值。

說明:在for迴圈的變數之前並沒有val或var的指定。該變數的型別是集合的元素型別。迴圈變數的作用域一直持續到迴圈結束。

在Scala中,對迴圈的使用並不如其他語言那麼頻繁。通常我們可以通過對序列中的所有值應用某個函式的方式來處理它們,而完成這項工作只需要一次方法呼叫即可。

說明:Scala並沒有提供break或continue語句來退出迴圈。那麼如果需要break時我們該怎麼做呢,有如下幾個選擇:

1、使用Boolean型的控制變數;

2、使用巢狀函式--你可以從函式當中return;

 3、使用Breaks物件中的break方法:

import scala.util.control.Breaks._
breakable {
  for (...) {
    if (...) break; //退出breakable塊
    ...
  }
}
在這裡,控制權的轉移是通過丟擲和捕獲異常完成的,因此,如果時間很重要的話,應該儘量避免使用這套機制。

高階for迴圈和for推導式

Scala中的for迴圈比起Java和C++功能要豐富的多。

1、可以以變數<-表示式的形式提供多個生成器,用分號將它們隔開。如:

  for(i <- 1 to 3; j <- 1 to 3) {
    print((10 * i + j) + " ");
  }

outputs: 11 12 13 21 22 23 31 32 33 

2、每個生成器都可以帶一個守衛,以if開頭的Boolean表示式:

for(i <- 1 to 3; j <- 1 to 3 <span style="color:#ff0000;">if i != j</span>) {
    print((10 * i + j) + " ");
  }

outputs: 12 13 21 23 31 32
注意在if之前並沒有分號

3、可以使用任意多的定義,引入可以在迴圈中使用的變數:

for(i <- 1 to 3; from = 4 - i; j <- from to 3) {
    print((10 * i + j) + " ");
  }

outputs: 13 22 23 31 32 33
4、如果for迴圈的迴圈體以yield開始,則該迴圈會構造出一個集合,每次迭代生成集合中的一個值:
<span style="font-size:18px;">for(i <- 1 to 10) yield {
      var r = i % 3
      print(r + " ")
  }

//生成 Vector(1, 2, 0, 1, 2, 0, 1, 2, 0, 1)
outputs: 1 2 0 1 2 0 1 2 0 1</span>

這類迴圈叫做for推導式。

for推導式生成的集合與它的第一個生成器是型別相容的。

for (c <- "Hello"; i <- 0 to 1) yield {
    var v = (c + i).toChar;
    print(v);
  }

outputs: HIeflmlmop

說明:如果你願意,你也可以將生成器、守衛和定義包含在花括號中,並可以以換行的方式而不是分號來隔開它們:
for{i <- 1 to 3
      from = 4 - i
      j <- from to 3 
    }
  print((10 * i + j) + " ")

outputs: 13 22 23 31 32 33

參考書籍:《快學Scala》