语句
语句 是 代码块 的组成部分,而代码块又是外部 表达式 或 函数 的组成部分。
声明语句
声明语句 是指将一个或多个名称引入到封闭语句块中的语句。声明的名称可以表示新的变量或新的 项。
声明语句有两种:项声明和 let
语句。
项声明
在语句块中声明项会将其 作用域 限制为包含该语句的块。该项不会被赋予 规范路径,它可能声明的任何子项也不会。
唯一的例外是,由 实现 定义的关联项只要该项以及(如果适用)特征是可访问的,仍然可以在外部作用域中访问。除此之外,它在含义上与在模块内部声明项相同。
不会隐式捕获包含函数的泛型参数、参数和局部变量。例如,inner
可能无法访问 outer_var
。
#![allow(unused)] fn main() { fn outer() { let outer_var = true; fn inner() { /* outer_var is not in scope here */ } inner(); } }
let
语句
语法
Let 语句 :
外部属性*let
PatternNoTopAlt (:
类型 )? (=
表达式 † (else
块表达式) ? ) ?;
† 当指定
else
代码块时,表达式 不能是 惰性布尔表达式,也不能以}
结尾。
let
语句 引入一组新的 变量,由 模式 给出。模式后面可以跟一个类型注解,然后结束,或者后面跟一个初始化表达式,加上一个可选的 else
代码块。
当没有给出类型注解时,编译器将推断类型,或者如果类型信息不足以进行明确的推断,则会发出错误信号。
由变量声明引入的任何变量,从声明点开始到封闭代码块作用域结束都是可见的,除非它们被另一个变量声明所遮蔽。
如果不存在 else
代码块,则模式必须是不可反驳的。如果存在 else
代码块,则模式可以是可反驳的。
如果模式不匹配(这要求它是可反驳的),则执行 else
代码块。else
代码块必须始终发散(求值为 never 类型)。
#![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!(); }; }
表达式语句
表达式语句 是指计算 表达式 并忽略其结果的语句。通常,表达式语句的目的是触发计算其表达式的效果。
仅由 块表达式 或控制流表达式组成的表达式,如果在允许使用语句的上下文中使用,则可以省略尾部分号。这可能会导致将其解析为独立语句还是作为另一个表达式的一部分之间产生歧义;在这种情况下,它被解析为语句。
当 带块表达式 用作语句时,其类型必须是单元类型。
#![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 }; }