首页 > 解决方案 > 为什么return语句后面的分号是可选的?

问题描述

我想遍历一个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(())
}

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

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

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

标签: rust

解决方案


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

问题的症结在于这return不是 Rust 中的语句(本身),而是返回1的表达式!

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

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

    Ok(())
}

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

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


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

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

因此,可选;的一个属性:

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

推荐阅读