因为分号在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

推荐答案

它们不是可选的.分号会修改表达式语句的行为,因此在代码行中是否使用分号应该是一个有意识的决定.

几乎所有 rust 迹斑斑的东西都是一种表达.表达式是返回值的东西.如果你用分号,你就是在 suppress 这个表达式的结果,在大多数情况下,这就是你想要的结果.

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

您可以在任何需要值的地方使用不带分号的表达式.

例如:

let a = {
    let inner = 2;
    inner * inner
};

此处表达式inner * inner不以分号结尾,因此其值不会被 suppress .因为它是块中的最后一个表达式,所以它的值将被返回并分配给a.如果在同一行上加上分号,则不会返回值inner * inner.

在您的特定情况下,不 suppress let语句的值是没有意义的,编译器正确地给了您一个错误.事实上,let不是一个表达.

Rust相关问答推荐

Box::new()会从一个堆栈复制到另一个堆吗?

通过解引用将值移出Box(以及它被脱糖到什么地方)?

为昂贵的for循环制作筛子

什么时候和为什么S最好是按值或引用传递简单类型

S在Cargo.toml中添加工作空间开发依赖关系的正确方法是什么?

可以为rust构建脚本编写单元测试吗?

在0..1之间将U64转换为F64

写入引用会更新基础值,但引用会打印意外的值

在铁 rust 中,如何一次只引用几件事中的一件?

Rust移动/复制涉及实际复制时进行检测

为什么 Rust 的临时值有时有参考性有时没有?

为什么数组不像向量那样在 for 块之后移动?

切片不能被 `usize` 索引?

Rust 引用元组和引用元组

如何使返回 XMLError 的方法与 anyhow::Error 兼容?

将 `&T` 转换为新类型 `&N`

试图理解 Rust 中的可变闭包

只有一个字符被读入作为词法分析器的输入

Rustfmt 是否有明确类型的选项?

为什么 `ref` 会导致此示例*取消引用*一个字段?