Rust言語の勉強を初めてみた。その5

# Control Flow

https://doc.rust-lang.org/book/ch03-05-control-flow.html

要は分岐とループ

## if Expressions

```
fn main() {
    let number = 3;

    if number < 5 {
        println!("condition was true");
    } else {
        println!("condition was false");
    }
}
```

分岐はifの後ろに条件式。続けて条件式がtrueの場合の処理を記述する。
上のコードを実行すると、condition was trueと表示される。
let number = 7;に変更して実行すると、condition was falseと表示される。

```
fn main() {
    let number = 3;

    if number {
        println!("number was three");
    }
}
```

このコードはビルドエラーになる。

![コメント 2020-08-19 095900.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624329/b2f1ea3c-d19b-ea6c-795f-47727724c24a.jpeg)

if文は非bool型を自動的に変換しない。
条件式は必ずboolでなければならない。

### Handling Multiple Conditions with else if

if - else if - elseで複数の条件を設定することができる。

```
fn main() {
    let number = 6;

    if number % 4 == 0 {
        println!("number is divisible by 4");
    } else if number % 3 == 0 {
        println!("number is divisible by 3");
    } else if number % 2 == 0 {
        println!("number is divisible by 2");
    } else {
        println!("number is not divisible by 4, 3, or 2");
    }
}
```

上のコードはnumber is divisible by 3と表示される。
if式は上から順番に評価される。
上のコードの場合、6 % 3 == 0の条件に該当し、それ以降の式は評価されない。

### Using if in a let Statement

```
fn main() {
    let condition = true;
    let number = if condition { 5 } else { 6 };

    println!("The value of number is: {}", number);
}
```

上のようなコードを実行すると、The value of number is: 5と表示される。
この場合、if文自体が式となり、評価の結果によってnumberの値が異なる。
また、ifブロックとelseブロックで同じ型でなければならない。
以下はビルドエラーとなる。

```
fn main() {
    let condition = true;

    let number = if condition { 5 } else { "six" };

    println!("The value of number is: {}", number);
}
```

![コメント 2020-08-19 095746.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624329/55a4707b-4225-19dc-0321-a7de92e3eaea.jpeg)

## Repetition with Loops

Rustにはloop、while、forの3種類のループがある。

### Repeating Code with loop

loopは明示的に停止を指示するまで永続的に処理を繰り返す。

```
fn main() {
    loop {
        println!("again!");
    }
}
```

上の式はagain!の出力をctrl+cを押すまで繰り返す。
ちなみにbreakでループを抜けることも出来る。

### Returning Values from Loops

以下の様なコードでloopの結果を設定することが出来る。

```
fn main() {
    let mut counter = 0;

    let result = loop {
        counter += 1;

        if counter == 10 {
            break counter * 2;
        }
    };

    println!("The result is {}", result);
}
```

breakに返す値を記述することを忘れてはいけない。
counterを0からカウントアップし、10になった時点でcounterを2倍し、返す。
上の処理結果は20となる。

### Conditional Loops with while

条件式がtrueである場合はループ処理を行い、trueでなくなった場合にループを終了する。

```
fn main() {
    let mut number = 3;

    while number != 0 {
        println!("{}!", number);

        number -= 1;
    }

    println!("LIFTOFF!!!");
}
```

numberが3からカウントダウンし、numberが0になった場合にループを終了する。

### Looping Through a Collection with for

whileを使って配列などのコレクション要素をループできる。

```
fn main() {
    let a = [10, 20, 30, 40, 50];
    let mut index = 0;

    while index < 5 {
        println!("the value is: {}", a[index]);

        index += 1;
    }
}
```

ただし、この場合はindexが配列要素の外を指すなどエラーが発生しやすい。
なので、このような処理はforループに置き換えることが出来る。

```
fn main() {
    let a = [10, 20, 30, 40, 50];

    for element in a.iter() {
        println!("the value is: {}", element);
    }
}
```

処理結果はwhileを使用した上のコードと同じになる。
こうすることで配列の要素をもれなく処理することが出来る。
こちらの方がより安全に処理できる。

カウントダウンさせる場合は、rev()を使用して、以下の様に書くことが出来る。

```
fn main() {
    for number in (1..4).rev() {
        println!("{}!", number);
    }
    println!("LIFTOFF!!!");
}
```