Error handling 如何返回带有一般错误的结果
我想写一个函数来读取文件的内容,如果失败了会引发一个错误。我想从一个python脚本调用这个函数,所以我在下面提到了一些python,以防它可能是相关的 正如我在评论中所尝试的那样,可能会发生更多导致其他类型错误的工作,因此如果可能的话,我希望在Rust(?)中使用一个通用错误。如何返回错误,以便在python错误中进行处理和包装,如Error handling 如何返回带有一般错误的结果,error-handling,rust,polymorphism,traits,trait-objects,Error Handling,Rust,Polymorphism,Traits,Trait Objects,我想写一个函数来读取文件的内容,如果失败了会引发一个错误。我想从一个python脚本调用这个函数,所以我在下面提到了一些python,以防它可能是相关的 正如我在评论中所尝试的那样,可能会发生更多导致其他类型错误的工作,因此如果可能的话,我希望在Rust(?)中使用一个通用错误。如何返回错误,以便在python错误中进行处理和包装,如do_work所示?不确定导致以下错误的方法是否正确 fn work_with_text() -> Result<(), dyn std::error:
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));
}
};
// ...
}
fn使用\u text()工作\u->结果{
让content=match std::fs::read_to_字符串(“text.txt”){
Ok(t)=>t,
Err(e)=>返回Err(e),
};
//对可能导致其他类型错误(rusqlite错误)的内容执行某些操作
好(())
}
#[pyfunction]
fn do_work(_py:Python)->PyResult{
将工作与文本()匹配{
正常()=>(0),
错误(e)=>{
让gil=Python::acquire_gil();
设py=gil.python();
让error_message=format!(“错误发生{}”,例如to_string());
PyIOError::新建错误(错误消息)。还原(py);
返回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)`
1 |。。。fn使用_text()->结果{
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^在编译时没有已知的大小
|
=帮助:未为`(dyn std::error::error+'static)实现特征'Sized'`
当前版本不起作用,因为trait对象没有静态已知的大小,这意味着编译器不知道在堆栈上为它们分配多少空间,因此不能将未调整大小的类型用作函数参数或返回值,除非通过将它们放在指针后面来调整大小
固定示例:
fn使用\u text()工作\u->结果{
让content=std::fs::读取字符串(“text.txt”)?;
//对可能导致其他类型错误(rusqlite错误)的内容执行某些操作
好(())
}
拥有框
还允许您从函数中返回多种错误,因为大多数错误类型可以通过?
操作符自动转换为框
如果您想更深入地了解Rust中的大小和错误处理,我强烈建议您阅读和。您当前的版本不起作用,因为trait对象没有静态已知的大小,这意味着编译器不知道在堆栈上为它们分配多少空间,因此不能将未大小的类型用作function参数或返回值,除非通过将它们放在指针后面来调整大小 固定示例:
fn使用\u text()工作\u->结果{
让content=std::fs::读取字符串(“text.txt”)?;
//对可能导致其他类型错误(rusqlite错误)的内容执行某些操作
好(())
}
拥有框
还允许您从函数中返回多种错误,因为大多数错误类型可以通过?
操作符自动转换为框
如果您想更深入地了解Rust中的大小和错误处理,我强烈建议您阅读和。
Box
是否有特殊原因,您希望将返回类型保留为Result
,而不是Result
,或者仅是std::io::Result
?@vallentin,因为我可能有其他类型的错误我认为std::io也不会涵盖ors,例如rusqliteerrors@SimenRussnes在这种情况下,创建自己的enum Error
以及每种错误的变体将更为惯用。而不是dyn std::Error::Error
。此外,FWIW您的匹配
是一种复杂的编写的方式nt=读取到字符串(…)?;
,如果可用和必要,后者将负责转换。框
是否有特殊原因,您希望将返回类型保留为结果
,而不是结果
,或者只是std::io::Result
?@vallentin,因为我可能还有其他类型的错误,我认为这些错误不会被涵盖通过std::io。例如rusqliteerrors@SimenRussnes在这种情况下,使用每种错误的变体创建自己的enum Error
将更为惯用。而不是dyn std::Error::Error
。此外,FWIW您的匹配
是一种复杂的编写让内容=读取到字符串(…)?;
,如有必要,后者将负责转换。