迴圈

有了迴圈,你可以告訴 Rust 繼續做某件事,直到你想停止它。你也能使用 loop 來啟動一個不會停止的迴圈,除非你告訴它何時 break(中斷)。

fn main() { // 這個程式永不停止
    loop {

    }
}

那讓我們告訴編譯器什麼時候能停止。

fn main() {
    let mut counter = 0; // 設定計數器為 0
    loop {
        counter +=1; // 計數器遞增 1
        println!("The counter is now: {}", counter);
        if counter == 5 { // 當計數器 == 5 時停止
            break;
        }
    }
}

將會印出:

The counter is now: 1
The counter is now: 2
The counter is now: 3
The counter is now: 4
The counter is now: 5

如果你的迴圈裡面還有迴圈,你可以給它們命名。有了名字,你可以告訴 Rust 要從哪個迴圈中 break 出來。使用 ' (稱為 "tick") 和 : 來給它命名:

fn main() {
    let mut counter = 0;
    let mut counter2 = 0;
    println!("Now entering the first loop.");

    'first_loop: loop {
        // 給第一個迴圈名字
        counter += 1;
        println!("The counter is now: {}", counter);
        if counter > 9 {
            // 在迴圈裡開始第二個迴圈
            println!("Now entering the second loop.");

            'second_loop: loop {
                // 現在我們在 'second_loop 裡面
                println!("The second counter is now: {}", counter2);
                counter2 += 1;
                if counter2 == 3 {
                    break 'first_loop; // 中斷到 'first_loop 標籤外我們才能離開程式
                }
            }
        }
    }
}

將會印出:

Now entering the first loop.
The counter is now: 1
The counter is now: 2
The counter is now: 3
The counter is now: 4
The counter is now: 5
The counter is now: 6
The counter is now: 7
The counter is now: 8
The counter is now: 9
The counter is now: 10
Now entering the second loop.
The second counter is now: 0
The second counter is now: 1
The second counter is now: 2

while 迴圈是指在某件事物還在 true 時繼續運作的迴圈。每一次迴圈,Rust 都會檢查它是否仍然是 true。如果變成 false,Rust 會停止迴圈。

fn main() {
    let mut counter = 0;

    while counter < 5 {
        counter +=1;
        println!("The counter is now: {}", counter);
    }
}

for 迴圈讓你告訴 Rust 每次要做什麼。但是在 for 迴圈中,迴圈會在一定次數後停止。for 迴圈經常使用範圍(range)。你能用 ....= 來建立範圍。

  • .. 建立一個排除的範圍: 0..3 建立 0, 1, 2
  • ..= 建立一個包含的範圍: 0..=3 建立 0, 1, 2, 3
fn main() {
    for number in 0..3 {
        println!("The number is: {}", number);
    }

    for number in 0..=3 {
        println!("The next number is: {}", number);
    }
}

印出:

The number is: 0
The number is: 1
The number is: 2
The next number is: 0
The next number is: 1
The next number is: 2
The next number is: 3

同時注意到,number 成為 0..3 的變數名。我們也能叫它做 n,或者 ntod_het___hno_f,或者任何名字。然後我們就可以在 println! 中使用這個名字。

如果你不需要變數名,就用 _

fn main() {
    for _ in 0..3 {
        println!("Printing the same thing three times");
    }
}

印出:

Printing the same thing three times
Printing the same thing three times
Printing the same thing three times

因為我們每次都沒有給它任何數字來列印。

而實際上,如果你給了變數名卻沒用,Rust 會告訴你:

fn main() {
    for number in 0..3 {
        println!("Printing the same thing three times");
    }
}

印出的內容和上面一樣。程式編譯正常,但 Rust 會提醒你沒有使用 number

warning: unused variable: `number`
 --> src\main.rs:2:9
  |
2 |     for number in 0..3 {
  |         ^^^^^^ help: if this is intentional, prefix it with an underscore: `_number`

Rust 建議寫 _number 而不是 _。在變數名前加上 _ 意味著 "也許我以後會用到它"。但是只用 _ 意味著"我根本不關心這個變數"。所以,如果你以後會使用它們,並且不想讓編譯器告訴你,你可以在變數名前面加上_

你也可以用 break 來回傳值。只要把值寫在 break 後面以及 ;。這個有 loop 和 break 的範例賦值給 my_number

fn main() {
    let mut counter = 5;
    let my_number = loop {
        counter +=1;
        if counter % 53 == 3 {
            break counter;
        }
    };
    println!("{}", my_number);
}

印出 56break counter; 的意思是"中斷並回傳計數器的值"。而且因為整個區塊以 let 開始,my_number 最後會得到回傳值。

現在我們知道了如何使用迴圈,對於我們之前的顏色"匹配"問題這是更好的解決方案。這個解決方案更好是因為我們要比較所有的東西,而"for"迴圈會檢視每一項元素。

fn match_colours(rbg: (i32, i32, i32)) {
    println!("Comparing a colour with {} red, {} blue, and {} green:", rbg.0, rbg.1, rbg.2);
    let new_vec = vec![(rbg.0, "red"), (rbg.1, "blue"), (rbg.2, "green")]; // 將顏色放進向量。裡面是含顏色名的元組
    let mut all_have_at_least_10 = true; // 從true開始。我們會設定為false如果其中一種顏色少於10
    for item in new_vec {
        if item.0 < 10 {
            all_have_at_least_10 = false; // 現在是false
            println!("Not much {}.", item.1) // 接著我們印出顏色。
        }
    }
    if all_have_at_least_10 { // 檢查是否仍是true,是就印出
        println!("Each colour has at least 10.")
    }
    println!(); // 多加一行
}

fn main() {
    let first = (200, 0, 0);
    let second = (50, 50, 50);
    let third = (200, 50, 0);

    match_colours(first);
    match_colours(second);
    match_colours(third);
}

印出:

Comparing a colour with 200 red, 0 blue, and 0 green:
Not much blue.
Not much green.

Comparing a colour with 50 red, 50 blue, and 50 green:
Each colour has at least 10.

Comparing a colour with 200 red, 50 blue, and 0 green:
Not much green.