Rust中的分号是否可选?

アレッ*_*ックス 31 syntax rust

由于分号在Rust中显然是可选的,为什么,如果我这样做:

fn fn1() -> i32 {    
    let a = 1
    let b = 2
    3
}
Run Code Online (Sandbox Code Playgroud)

我收到错误:

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
Run Code Online (Sandbox Code Playgroud)

Gil*_*les 73

它们不是可选的.分号修改表达式语句的行为,因此无论是否使用它们代码行,都应该有意识地做出决定.

Rust中的几乎所有内容都是表达式.表达式是返回值的东西.如果你输了一个分号,你就会抑制这个表达式的结果,这在大多数情况下都是你想要的.

另一方面,这意味着如果使用不带分号的表达式结束函数,将返回最后一个表达式的结果.同样可以应用于match语句中的块.

您可以在没有分号的情况下使用表达式的表达式.

例如:

let a = {
    let inner = 2;
    inner * inner
};
Run Code Online (Sandbox Code Playgroud)

这里的表达式inner * inner不以分号结尾,因此不会抑制其值.由于它是块中的最后一个表达式,因此将返回其值并将其赋值给a.如果在同一行上放置分号,inner * inner则不会返回值.

在您的特定情况下,不抑制let语句的值没有意义,编译器正确地为您提供错误.事实上,let不是表达.

  • 您还可以查看这个 https://rustbyexample.com/expression.html 关于也提到分号的表达式。 (2认同)

Min*_*uel 6

分号通常不是可选的,但在某些情况下它们是可选的。即后控制表达式喜欢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);
    };
}
Run Code Online (Sandbox Code Playgroud)

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

(在某些情况下,您确实需要为这些语句使用或不使用分号。如果您从内部返回值,则不能使用分号,并且如果您将变量设置为来自内部的值需要一个分号。)