見出し画像

フロー制御


式と文

  • Rustは式ベースの言語

  • 式の例

    • if / match

    • for / while

  • 文の例

    • print!や変数宣言など、式以外のすべて

  • 式にはセミコロンを付けない
    関数の最後にセミコロンを付けない⇒式として認識される⇒戻り値

ブロック

Rustでは{ }で囲まれた部分をブロックという。
関数や条件分岐、loopで使用する{ }もブロックである。
ブロックは単体でも使用することができる。
ブロック単体で処理フローに変化はなく、上から順に実行されていく。

fn main() {
    println!("Hello");
    {
        println!("World!");
    }
    println!("Rust (V)^^(V)");
}
$ cargo run

Hello
World!
Rust (V)^^(V)

ブロックの内側で宣言された変数を、ブロックの外側で使用することはできない。

fn main() {

    {
        let x = 1;
    }
    println!("{}", x);
    // error
    // cannot find value `x` in this scoperustcClick for full compiler diagnostic
    // main.rs(4, 13): the binding `x` is available in a different scope in the same function

}

逆に、ブロックの外側で宣言された変数を、ブロックの内側で使うことは可能。

fn main() {

    let x = 1;
    {
        println!("{}", x);
    }
}
$ cargo run

1

変数が使用できる範囲のことをスコープという。
プログラムのすべての範囲で扱えるスコープのことをグローバルスコープという。

シャドウイングすると以下のようになる。

fn main() {
    let x = 1;
    println!("1.ブロックの外:{}", x);
    {
        let x = 2;
        println!("2.ブロックの中:{}", x);
    }
    println!("3.ブロックの外:{}", x);
}
$ cargo run

1.ブロックの外:1
2.ブロックの中:2
3.ブロックの外:1

if

pythonやJavaScriptのような言語は、0以外の数値がTrueで0がFalseであったり、要素が存在する配列がTrue、空の配列がFalseといった判定が行われるものもあるが、Rustは厳密で条件部分は必ず論理型である必要がある。

fn main() {
    let x = 5;
    // pythonやJavaScriptのような言語は0以外の数値がTrueで0がFalseであったり、要素が存在する配列がTrue、空の配列がFalseといった判定が行われるものもあるが、Rustは厳密で条件部分は必ず論理型である必要がある
    if x > 0 {
        println!("x={}のとき、x>0 は True", x);
    }
}
$ cargo run

x=5のとき、x>0True

And条件、Or条件、複数の条件分岐

fn main() {
    let x = 5;

    // And条件
    if x > 0 && x < 10 {
        println!("x={}のとき、x > 0 && x < 10 は True", x);
    }

    // Or条件
    if x > 0 || x <= 10 {
        println!("x={}のとき、x > 0 || x <= 10 は True", x);
    }

    // 複数の条件分岐を追加したい場合
    if x > 0 || x <= 10 {
        println!("x={}のとき、x > 0 || x <= 10 は True", x);
    } else if x > 11 && x <= 20 {
        println!("x={}のとき、x > 11 && x <= 20 は True", x);
    } else {
        println!("x={}のときは、この条件には当てはまらない。", x);
    }

}
$ cargo run

x=5のとき、x > 0 && x < 10True
x=5のとき、x > 0 || x <= 10True
x=5のとき、x > 0 || x <= 10True

if は文ではなく、式であるため、値を返したり変数に束縛することができる。ただし、値を返す場合elseですべての分岐で必ず何かしらの値を返すようにする必要がある。
またすべての分岐で戻り値の型をそろえる必要がある。
戻り値の値に異なる型が含まれる場合、コンパイルエラーになる。

fn main() {
    let x = 5;

    let y = if x > 10 {
        x
    } else {
        0
    };
    println!("y={}", y);

}
$ cargo run

y=0


この記事が気に入ったらサポートをしてみませんか?