语句
Syntax
Statement →
;
| Item
| LetStatement
| ExpressionStatement
| OuterAttribute* MacroInvocationSemi
语句(Statement)是块的组成部分,而块又是外部表达式或函数的组成部分。
声明语句
声明语句是将一个或多个名称引入封闭语句块的语句。声明的名称可以表示新变量或新项。
两种声明语句是项声明和 let 语句。
项声明
在语句块中声明项会将其作用域限制为包含该语句的块。该项不会被赋予规范路径,其可能声明的任何子项也不会。
例外情况是,只要该项(如果适用,还有 trait)可访问,实现定义的关联项仍然可以在外部作用域中访问。否则,它在含义上与在模块内声明该项相同。
没有隐式捕获包含函数的泛型参数、参数和局部变量。例如,inner 不能访问 outer_var。
#![allow(unused)]
fn main() {
fn outer() {
let outer_var = true;
fn inner() { /* outer_var is not in scope here */ }
inner();
}
}
let 语句
Syntax
LetStatement →
OuterAttribute* let PatternNoTopAlt ( : Type )?
(
= Expression
| = Expressionexcept LazyBooleanExpression or end with a }
else BlockExpressionNoInnerAttributes
)? ;
let 语句引入一组新的变量,由模式给出。模式后面可以选择性地跟类型标注,然后结束,或者后跟初始化器表达式加上可选的 else 块。
当未给出类型标注时,编译器将推断类型,或者如果类型信息不足无法进行确定性推断则发出错误信号。
变量声明引入的任何变量从声明点到封闭块作用域结束都是可见的,除非它们被另一个变量声明遮蔽。
如果不存在 else 块,则模式必须是不可反驳的。如果存在 else 块,则模式可以是可反驳的。
如果模式不匹配(这要求它是可反驳的),则执行 else 块。else 块必须始终发散(求值为永不类型)。
#![allow(unused)]
fn main() {
let (mut v, w) = (vec![1, 2, 3], 42); // The bindings may be mut or const
let Some(t) = v.pop() else { // Refutable patterns require an else block
panic!(); // The else block must diverge
};
let [u, v] = [v[0], v[1]] else { // This pattern is irrefutable, so the compiler
// will lint as the else block is redundant.
panic!();
};
}
表达式语句
Syntax
ExpressionStatement →
ExpressionWithoutBlock ;
| ExpressionWithBlock ;?
表达式语句是求值表达式并忽略其结果的语句。通常,表达式语句的目的是触发求值其表达式的效果。
仅由块表达式或控制流表达式组成的表达式,如果在允许语句的上下文中使用,可以省略尾部分号。这可能会在将其解析为独立语句还是另一个表达式的一部分之间产生歧义;在这种情况下,它被解析为语句。
用作语句时 ExpressionWithBlock 表达式的类型必须是单元类型。
#![allow(unused)]
fn main() {
let mut v = vec![1, 2, 3];
v.pop(); // Ignore the element returned from pop
if v.is_empty() {
v.push(5);
} else {
v.remove(0);
} // Semicolon can be omitted.
[1]; // Separate expression statement, not an indexing expression.
}
当省略尾部分号时,结果必须是类型 ()。
#![allow(unused)]
fn main() {
// bad: the block's type is i32, not ()
// Error: expected `()` because of default return type
// if true {
// 1
// }
// good: the block's type is i32
if true {
1
} else {
2
};
}