语句
语法
Statement :
;
| 项
| LetStatement
| ExpressionStatement
| MacroInvocationSemi
语句 是 块 的一个组成部分,而块本身又是外部 表达式 或 函数 的一个组成部分。
声明语句
声明语句 会将一个或多个 名称 引入到其所在的语句块中。声明的名称可以指代新的变量或新的 项。
声明语句有两种:项声明和 let
语句。
项声明
在语句块内声明一个项会将其 作用域 限制在该语句所在的块中。该项不会被赋予 规范路径,其声明的任何子项也不会。
此规则的例外是,由 实现 定义的关联项(associated items)只要该项以及适用的特质(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
语句
语法
LetStatement :
外部属性*let
PatternNoTopAlt (:
类型 )? (=
表达式 † (else
块表达式) ? ) ?;
† 当指定了
else
块时,该 表达式 不能是 LazyBooleanExpression,也不能以}
结尾。
let
语句 引入一组新的 变量,这些变量由一个 模式 给出。模式后面可以可选地跟着类型标注,然后要么结束,要么跟着一个初始化表达式和一个可选的 else
块。
如果没有给出类型标注,编译器将推断类型;如果类型信息不足以进行确定性推断,则会发出错误信号。
由变量声明引入的任何变量从声明点开始直到其所在块作用域结束都可见,除非被另一个变量声明所遮蔽(shadowed)。
如果不存在 else
块,则模式必须是不可驳的(irrefutable)。如果存在 else
块,则模式可以是可驳的(refutable)。
如果模式不匹配(这要求模式是可驳的),则执行 else
块。else
块必须总是发散(diverge,求值为 never type)。
#![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!(); }; }
表达式语句
表达式语句 是一个求值 表达式 并忽略其结果的语句。通常,表达式语句的目的是触发对其表达式求值的附带效果。
一个只包含 块表达式 或控制流表达式的表达式,如果在允许语句出现的上下文中,可以省略末尾的分号。这可能导致将其解析为独立语句与解析为另一个表达式的一部分之间产生歧义;在这种情况下,它被解析为语句。
当 带块的表达式 用作语句时,其类型必须是单元类型(unit type)。
#![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 }; }