为什么 return 语句后面的分号是可选的?

Ric*_*aca 3 rust

我想遍历Options的列表。如果其中之一有值,我想返回一个错误。这是一个人为的例子:

fn test(options: &[Option<u8>]) -> Result<(), &u8> {
    for option in options {
        match option {
            None => (),
            Some(value) => {
                // do some stuff here, so I can't just go
                // Some(value) => return Err(value),
                return Err(value); // this semicolon is optional
            }
        }
    }

    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

添加另一个分号会导致错误,但删除分号不会。

为什么 return 语句后面的分号是可选的?

在惯用的 Rust 中应该使用哪种形式:分号还是没有分号?两者都被编译器接受并且似乎产生相同的结果。

Mat*_* M. 8

为什么 return 语句后面的分号是可选的?

问题的关键是这return不是 Rust 中的语句(本身),它是一个返回1表达式!

这意味着您的测试用例的惯用格式实际上是:

fn test(options: &[Option<u8>]) -> Result<(), &u8> {
    for option in options {
        match option {
            None => (),
            Some(value) => return Err(value),
        }
    }

    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

请注意,我删除{}return表达式的周围。右边=>是一个表达式,return Err(value)是一个表达式,它很适合,不需要额外的绒毛。

1 !表示编程语言理论中的底层类型,一种没有实例的类型,用于表示发散的表达式。它也被称为 NEVER 类型。


分号在 Rust是可选的吗?在 Rust 中,表达式可以通过添加一个;.

由于右侧=>需要一个表达式,你不能直接使用return Err(value);(因为它现在是一个语句)但你可以使用一个恰好包含语句的块表达式,可能还有一个最终表达式。

;因此,可选是的属性:

  • 包含单个语句的块,没有最终表达式:{ return Err(value); }。它的类型是().
  • 仅包含最终表达式的块:{ return Err(value) }. 它的类型是!.


Alo*_*oso 5

此处;可以省略,因为return是一个计算结果为!type 的表达式,然后将其强制为空元组(),因此所有匹配臂都具有相同的类型。

在惯用的 Rust 中应该使用哪种形式?

添加;或删除周围的花括号是惯用的做法。这也是这么做cargo fmt的。