如何 Return 具有一般错误的结果

How to Return a Result with generic error

我想编写一个函数来读取文件的内容,并在失败时引发错误。我想从 python 脚本调用此函数,因此我在下面提到了一些 Python 以防它可能相关。

正如我在评论中尝试展示的那样,可能会发生更多引发其他类型错误的工作,所以如果可能的话,我想使用一般错误,如果这在 Rust(?) 中是可能的。我怎样才能 return 错误,以便可以处理它并将其包装在 python 错误中,如 do_work 所示?不确定导致以下错误的方法是否正确。

fn work_with_text() -> Result<(), dyn std::error::Error> {
    let content = match std::fs::read_to_string("text.txt") {
        Ok(t) => t,
        Err(e) => return Err(e),
    };
    // do something with content that may cause another type of error (rusqlite error)
    Ok(())
}
    

#[pyfunction]
fn do_work(_py: Python) -> PyResult<u32> {
    match work_with_text() {
        Ok(_) => (0),
        Err(e) => {
            let gil = Python::acquire_gil();
            let py = gil.python();
            let error_message = format!("Error happened {}", e.to_string());
            PyIOError::new_err(error_message).restore(py);
            return Err(PyErr::fetch(py));
        }
    };

    // ...
}

错误:

1   | ...                   fn work_with_text() -> Result<(), dyn std::error::Error> {
    |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `(dyn std::error::Error + 'static)`

您当前的版本不起作用,因为特征对象没有静态已知大小,这意味着编译器不知道在堆栈上为它们分配多少space,所以您可以'不要使用未调整大小的类型作为函数参数或 return 值 除非你通过将它们放在指针后面来调整它们的大小

固定示例:

fn work_with_text() -> Result<(), Box<dyn std::error::Error>> {
    let content = std::fs::read_to_string("text.txt")?;
    // do something with content that may cause another type of error (rusqlite error)
    Ok(())
}

拥有 Box<dyn std::error::Error> 还可以让您 return 函数中的各种错误,因为大多数错误类型可以通过 [=13= 自动转换为 Box<dyn std::error::Error> ] 运算符。

如果您想更深入地了解 Rust 中的大小和错误处理,我强烈建议您阅读 Sizedness in Rust and Error Handling in Rust