Rust 函数“loop{}”返回“->!”有什么不同?并且什么也不返回?

sni*_*per 6 rust

我在 Rust 中遇到了这个函数:

#[no_mangle]
 pub extern "C" fn _start() -> ! {
    loop {}
}
Run Code Online (Sandbox Code Playgroud)

从这里的答案:“->!”是什么意思?在 Rust 中 ,我理解它永远不会返回。

上面的函数和下面没有任何返回的函数有什么区别?

#[no_mangle]
 pub extern "C" fn _start() {
    loop {}
}
Run Code Online (Sandbox Code Playgroud)

我能够编译两者。

Sil*_*olo 4

没有显式返回类型的 Rust 函数相当于显式标记返回类型()(发音为“unit”)的函数。这相当于voidC++ 系列语言中的情况。所以

fn example() {
    loop {}
}
Run Code Online (Sandbox Code Playgroud)

相当于

fn example() -> () {
    loop {}
}
Run Code Online (Sandbox Code Playgroud)

它实际上“忽略”了返回值。所以如果我们有一个bar()返回 的函数i32,那么

fn foo() -> i32 {
    bar()
}
Run Code Online (Sandbox Code Playgroud)

是一个返回 的结果的函数bar,而

fn foo() {
    bar()
}
Run Code Online (Sandbox Code Playgroud)

是一个调用bar然后丢弃其返回值的函数。

!(发音为“never”)在 Rust 中有点特殊。类型的值!可以分配给任何类型的变量。另一方面,则()是普通型。因此,如果我们在一条语句的一个分支中调用函数!的版本,那么它会很高兴地与该函数的返回类型共存。examplematchmatch

match foo() {
    Some(x) => 0,
    None => example(),
}
Run Code Online (Sandbox Code Playgroud)

example会同意这一点match,因为它将永远循环(或恐慌)并且永远不会返回。但是()的版本example将无法编译,因为()i32不是同一类型。

总之,如果您可以显式地将函数标记为 returned !,那么您应该这样做。返回类型!总是比 之一更好(),因为前者可以转换为后者。