【问题标题】:Why does a standard error need to be boxed in main, but not an io error?为什么标准错误需要在main中装箱,而不是io错误?
【发布时间】:2020-03-08 17:56:18
【问题描述】:

取如下代码sn-p:

fn main() -> std::result::Result<(), std::io::Error> {
    println!("Bonjour le Monde");
    Ok(())
}

这是非常好的代码,但我想知道如果我将错误的类型更改为 std::error::Error: 会发生什么:

fn main() -> std::result::Result<(), std::error::Error> {
    println!("Bonjour le Monde");
    Ok(())
}

这已经不好了:

错误[E0277]:在编译时无法知道(dyn std::error::Error + 'static) 类型值的大小

我是这样解决的:

fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("Bonjour le Monde");
    Ok(())
}

那么为什么 main 函数需要 Box 处理标准错误,而不需要处理 io 错误?

【问题讨论】:

    标签: error-handling compiler-errors rust


    【解决方案1】:

    std::error::Error 是标准库中包含的特征。正如 Rust 指出的那样,它无法确定在编译时存储 Error 需要多少内存,因为可能会使用任何大小的结构。因此,您需要使用某种形式的间接寻址,例如引用、指针,或者在本例中为Box。有关使用 trait 对象的更多信息,请参阅 TRPL Ch.17

    相比之下,std::io::Error 是来自std::io 模块的结构(它也恰好实现了std::error::Error)。 Rust 确实知道这个结构很大,所以它可以创建一个使用它的 Result 的单态。

    【讨论】:

    • 太好了,这很有帮助。 Rust 如何知道 std::io::Error 结构有多大? io错误是否受特定高字节大小的限制?
    • @PaulRazvanBerg 所有结构都有固定大小。如果您查看std::io::Error 的定义,您会发现它只包含一个成员,即枚举ReprRepr 本身是 1) i32,2) 普通枚举 SimpleError,或 3) Box,因此整个 io::Error 结构占用 Repr 的最大变体的大小(可能是 @ 987654338@),加上一些额外的存储变量标签。在我的系统上,由于对齐,它占用16字节,但在32位系统上,它可能只占用8字节。
    猜你喜欢
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 2011-01-07
    • 2023-03-15
    相关资源
    最近更新 更多