rust - 为什么 Rust 允许返回类型错误的代码,但只允许尾随分号?

标签 rust return-type unreachable-code

考虑以下 Rust 代码:

fn f() -> i32 {
    loop {
        println!("Infinite loop!");
    }
    println!("Unreachable");
}

尽管返回类型错误,它仍会编译(带有警告)并运行。
编译器似乎可以接受 () 的返回类型在最后一行,因为它检测到此代码不可访问。

但是,如果我们删除最后一个分号:

fn f() -> i32 {
    loop {
        println!("Infinite loop!");
    }
    println!("Unreachable")
}

然后代码不再编译,出现类型错误:
error[E0308]: mismatched types
  --> src/main.rs:14:5
   |
14 |     println!("Unreachable")
   |     ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `()`
   |
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

为什么是这样?返回类型不一样吗,() ,在这两个代码片段中?

注意:我有兴趣了解为什么 Rust 编译器在这两个示例中表现不同,即 Rust 编译器是如何实现的。从语言设计的角度来看,我并不是要问一个关于它“应该”如何表现的哲学问题(我知道这样的问题可能是题外话)。

最佳答案

第一个代码块中的返回类型实际上是! (称为从不),因为你有一个永远不会退出的循环(所以 rust 会给你一个警告,说它无法访问)。完整的类型是:
fn f() -> !
我怀疑 !更像是 Rust 中的“底部”类型,而不是其他任何东西。在第二种情况下,由于 i32 和 () 在编译器进行“不可达性”分析之前不匹配,您的函数可能会在类型检查的早期阶段出错,就像在第一个示例中一样。

编辑:按照建议,这里是 rust book https://doc.rust-lang.org/book/ch19-04-advanced-types.html#the-never-type-that-never-returns 的相关部分

关于rust - 为什么 Rust 允许返回类型错误的代码,但只允许尾随分号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60330870/

相关文章:

python - 将 Pandas 函数应用于列以创建多个新列?

flash - 可以返回两种类型的方法的 AS3 最佳实践

soap - 如何通过 Web 服务发送 ArrayList?

java - 为什么代码无法访问?

java - For 循环 Java 无法访问语句

rust - &[u8] 不能被 RangeFull 索引?

winapi - CertOpenSystemsStoreW 或 CertCloseStore 的 Rust FFI 声明有什么问题?

docker - 无法使用 Rust 可执行文件运行 Docker 镜像

rust - 在 Rust 的 HashMap<(String, usize), f64> 中查找键

Ada 抑制无法访问的代码或缺少返回