web-dev-qa-db-ja.com

Rustではセミコロンはオプションですか?

セミコロンは明らかにRustではオプションなので、なぜ私がこれをすると:

fn fn1() -> i32 {    
    let a = 1
    let b = 2
    3
}

エラーが発生します:

error: expected one of `.`, `;`, `?`, or an operator, found `let`
 --> src/main.rs:3:9
  |
2 |         let a = 1
  |                  - expected one of `.`, `;`, `?`, or an operator here
3 |         let b = 2
  |         ^^^ unexpected token
35
アレックス

それらはオプションではありません。セミコロンは式ステートメントの動作を変更するため、コード行で使用するかどうかを意識的に決定する必要があります。

Rustのほとんどすべてが式です。式は値を返すものです。セミコロンを置くと、この式の結果が抑制されます。ほとんどの場合、これが必要です。

一方、セミコロンのない式で関数を終了すると、最後の式の結果が返されます。同じことがmatchステートメントのブロックにも適用できます。

値が期待される他の場所では、セミコロンなしの式を使用できます。

例えば:

let a = {
    let inner = 2;
    inner * inner
};

ここで、式inner * innerはセミコロンで終わっていないため、その値は抑制されません。これはブロックの最後の式なので、その値が返され、aに割り当てられます。同じ行にセミコロンを付けると、inner * innerの値は返されません。

特定のケースでは、letステートメントの値を抑制しないことは意味がなく、コンパイラーがエラーを正しく表示しています。実際、letは式ではありません。

78
Gilles

セミコロンは一般にオプションではありませんが、オプションの場合もあります。つまり、forif/elsematchなどの制御式の後。

fn main() {
    let a: u32 = 5;
    if 5 == a {
        println!("Hello!");
    }
    if 5 == a {
        println!("Hello!");
    };
    for x in "World".chars() {
        println!("{}", x);
    }
    for x in "World".chars() {
        println!("{}", x);
    };
}

https://play.Rust-lang.org/?version=stable&mode=debug&edition=2018&Gist=1bf94760dccae285a2bdc9c44e8f658a

(これらのステートメントにセミコロンを付ける必要がある場合とそうでない場合があります。内部から値を返す場合、セミコロンを付けることはできず、変数を内部からの値に設定する場合セミコロンが必要です。)

2
Mingwei Samuel