为什么可以在没有分号的情况下定义 Rust 结构?

Geo*_*lin 4 rust

我正在学习 Rust,结构一章给出了一个;在末尾没有 a 的结构的例子。它可以编译,但我不知道为什么允许这样做。

fn main() {
    struct User {
        username: String,
        email: String,
        sign_in_count: u64,
        active: bool,
    }
}
Run Code Online (Sandbox Code Playgroud)

...实际上,同样的问题也适用于函数。

Mas*_*ara 7

正如 Shepmaster 在评论中所说,“原因”是 Rust 如此定义。下面我将解释它背后的规则。

基本上你可以省略;}. 这将回答您的问题。

但是,该规则有许多例外情况:

{}间接出现

上述规则在{}间接出现时不适用,例如

use std::io::{self, Read, Write}; // Here }; appears
Run Code Online (Sandbox Code Playgroud)

或者

let x = if cond {
    1
} else {
    2
}; // Here }; appears
Run Code Online (Sandbox Code Playgroud)

在这种情况下,{}不是use/的直接部分let。所以在这种情况下你需要;.

项目

项目是您也可以放置在函数之外的东西。也就是说,一个extern crateusemodstructenumuniontypetraitimplfnstaticconstextern,和宏。

您可以将项目放置在函数之外或函数中。但是,它们之间有一个区别:

  • 如果它出现在函数之外,则在不必要时必须省略;
  • 如果它出现在一个函数中,你也可以放在;那里。这基本上是因为;本身就是一个空语句

例子:

struct A {} // You can't place ; here
fn main() {
    struct B {} // You can omit ; here
    struct C {}; // You can also place ; here
}
Run Code Online (Sandbox Code Playgroud)

最后一个表情

你必须省略;如果

  • 它是块中的最后一条语句,
  • 它是一个表达式(项目而let不是表达式),并且
  • 您想从表达式中返回值。

例子:

fn f() -> i32 {
    let x = 1;
    x + x // You want to return x + x, so you can't place `;` here
}
Run Code Online (Sandbox Code Playgroud)

块表达式

if, if let, match, loop, while, while let, for, unsafe, 和裸{}结束},所以你可以省略;它们。但是,如果放在;这里,会有轻微的影响。

例子:

fn f(x: i32) -> i32 {
    if x < 10 {
        10
    } else {
        20
    }; // If you remove ; here, then you will see a compile error.
    42
}
Run Code Online (Sandbox Code Playgroud)

大多数情况下,您不必放置;在这里;相反,您可能必须放置;在块中。

fn f(x: i32) -> i32 {
    if x < 10 {
        10;
    } else {
        20;
    }
    42
}
Run Code Online (Sandbox Code Playgroud)

语句宏

在语句位置中,您可以编写三种不同的宏:

  • some_macro!()/ some_macro![]:这实际上不是一个语句宏;相反,这只是一个表达式宏。它不能扩展到 items 或let.
  • some_macro!{}:这扩展到零个或多个语句。
  • some_macro!();/ some_macro![];/ some_macro!{};:这也扩展到零个或多个陈述; 但是,有一个非常小的区别:;添加到最后一个扩展语句中。