由于在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
答案 0 :(得分:64)
他们不是可选的。分号修改表达式语句的行为,因此无论是否使用它们,都应该有意识地决定代码行。
Rust中几乎所有东西都是表达式。表达式是返回值的东西。如果你输了一个分号,你就会抑制这个表达式的结果,这在大多数情况下都是你想要的。
另一方面,这意味着如果使用不带分号的表达式结束函数,将返回最后一个表达式的结果。同样可以应用于match
语句中的块。
您可以在没有分号的地方使用没有分号的表达式。
例如:
let a = {
let inner = 2;
inner * inner
};
此处表达式inner * inner
不以分号结尾,因此不会抑制其值。由于它是块中的最后一个表达式,因此将返回其值并将其分配给a
。如果在同一行上放置分号,则不会返回inner * inner
的值。
在您的特定情况下,不抑制let
语句的值没有意义,编译器正确地为您提供错误。实际上,let
不是表达式。
答案 1 :(得分:6)
分号通常不是可选的,但是在某些情况下是分号。即在for
,if/else
,match
等控件表达式之后。
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);
};
}
(在某些情况下,您确实需要为这些语句使用分号。如果要从内部返回值,则不能使用分号,并且要将变量设置为值从内部您需要一个分号。)