「ループ」を終了するときに「ブレーク」にセミコロンが必要ないのはなぜですか?

Nov 26 2020

Rust Bookの第3.5章からの抜粋:

...breakキーワードと値を使用しますcounter * 2。ループの後、セミコロンを使用して、値をに割り当てるステートメントを終了しresultます。

さらに、コードスニペット:

fn main() {
    let mut counter = 0;

    let result = loop {
        counter += 1;

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

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

これがどのように機能し、結果が20になるのかは理解していますが、「break」キーワードを含む行のセミコロンを削除すると、プログラムは同等であることに気付きました。

この場合、セミコロンがオプションであるのはなぜですか?

回答

5 E_net4thecurator Nov 26 2020 at 22:30

短い例:

let _: i32 = loop {
    if true {
        break 3; // ()
    }
};

これは、セミコロンが意図した結果に干渉しないもう1つの例です。1つは、セミコロンを挿入すると、ユニットタイプに評価される式ステートメントが導入され()ます。loopsおよびif式が同じ型に評価するコードブロックを認めざるを得続け()、その後、すべての種類が適合しています。

let _: i32 = loop {
    if true {
        break 3 // !
    }
};

セミコロンが削除breakされると、はnever型に!評価され、他の型に強制変換されます。これは、外部スコープで期待されるすべてのタイプを満たすことを意味します。したがって、ifブロックの終わりの前に他のステートメントを追加しようとしない限り、すべてがまったく同じです。

それらの副作用は、プログラムが自然なワークフローを通過しないことを意味するため、breakとの両方をreturn評価し!ます。

参照:

  • 戻り式が不要なのにセミコロンを使用するのはなぜですか?
  • Rustでreturnステートメントを使用することとセミコロンを省略することの違いは何ですか?
  • 関数の終わりを静的にアサートする方法に到達できません
3 pretzelhammer Nov 26 2020 at 22:42

式ステートメントに関するRust言語リファレンス:

式文は式を評価し、その結果を無視するものです。原則として、式ステートメントの目的は、その式を評価する効果をトリガーすることです。

ブロック式または制御フロー式のみで構成される式は、ステートメントが許可されているコンテキストで使用される場合、末尾のセミコロンを省略できます。

ほとんどすべてがRustの表現であるため、これは純粋に美学と人間工学のためのものだと思います。すべての式の後に末尾のセミコロンが必須である場合は、if-elseブロック(式でもあります)をひどいセミコロンで終了する必要があります。

if {
    // do something
} else {
    // do something else
}; // <- gross

同様に、すべての制御フロー式の末尾のセミコロンは制御フローを生成するため省略できます。そのため、式の結果を破棄して()代わりに評価するというセミコロンの一般的な機能は無関係になります。

fn five() -> i32 {
    return 5 // to semicolon or not to semicolon? it doesn't matter
}

上記の例ではreturn 5、セミコロンで終了しても、制御フローを生成するため、その式の結果を「キャプチャ」することはできないため、違いはありません。breakやなどの他の制御フロー式についても同じことが言えますcontinue