Error handling Rust`From`trait,errors,reference vs Box和`?`运算符
我对返回Error handling Rust`From`trait,errors,reference vs Box和`?`运算符,error-handling,rust,Error Handling,Rust,我对返回结果的函数中的?运算符感到非常困惑 我有以下代码片段: use std::error; use std::fs; fn foo(s: &str) -> Result<&str, Box<error::Error>> { let result = fs::read_to_string(s)?; return Ok(&result); } fn bar(s: &str) -> Result<&am
结果的函数中的?
运算符感到非常困惑
我有以下代码片段:
use std::error;
use std::fs;
fn foo(s: &str) -> Result<&str, Box<error::Error>> {
let result = fs::read_to_string(s)?;
return Ok(&result);
}
fn bar(s: &str) -> Result<&str, &dyn error::Error> {
// the trait `std::convert::From<std::io::Error>` is not implemented for `&dyn std::error::Error` (1)
let result = fs::read_to_string(s)?;
return Ok(&result);
}
fn main() {
println!("{}", foo("foo.txt").unwrap());
println!("{}", bar("bar.txt").unwrap());
}
使用std::error;
使用std::fs;
fn foo(s:&str)->结果{
让result=fs::读取到字符串?;
返回Ok(&结果);
}
fn条(s:&str)->结果{
//特性'std::convert::From'未为`&dyn std::error::error`(1)实现
让result=fs::读取到字符串?;
返回Ok(&结果);
}
fn main(){
println!(“{}”,foo(“foo.txt”).unwrap();
println!(“{}”,bar(“bar.txt”).unwrap();
}
从上面的代码段中可以看到,?
运算符可以很好地处理返回的装箱错误,但不能处理动态错误引用(错误位于(1)
)
有没有什么具体的原因导致它不起作用?就我对Rust的有限了解而言,返回错误引用比返回装箱对象更为自然:最后,在从foo
函数返回后,我希望deref强制能够使用它,那么为什么不返回错误引用本身呢?看看这个函数签名:
fn bar(s: &str) -> Result<&str, &dyn error::Error> {
这个特性没有实现,也不可能实现。要了解原因,请尝试手动执行:
impl<'a> From<io::Error> for &'a dyn error::Error {
fn from(e: io::Error) -> &'a dyn error::Error {
// what can go here?
}
}
impl&'a dyn error::error{
//你能在这里做什么?
}
}
出于完全相同的原因,这种方法不可能实现
为什么它适用于框
?Box
在堆上分配其数据,但也拥有该数据,并在Box超出范围时解除分配该数据。这与引用是完全不同的,在引用中所有者是独立的,并且通过类型中的生存期参数阻止引用延长数据的时间
另见:
查看此函数签名:
fn bar(s: &str) -> Result<&str, &dyn error::Error> {
这个特性没有实现,也不可能实现。要了解原因,请尝试手动执行:
impl<'a> From<io::Error> for &'a dyn error::Error {
fn from(e: io::Error) -> &'a dyn error::Error {
// what can go here?
}
}
impl&'a dyn error::error{
//你能在这里做什么?
}
}
出于完全相同的原因,这种方法不可能实现
为什么它适用于框
?Box
在堆上分配其数据,但也拥有该数据,并在Box超出范围时解除分配该数据。这与引用是完全不同的,在引用中所有者是独立的,并且通过类型中的生存期参数阻止引用延长数据的时间
另见:
尽管可以将具体类型std::io::Error
转换为dyn Error
,但无法将其作为引用返回,因为“owned”值在函数末尾被删除/擦除/删除,这同样适用于字符串->&str
。Box
示例之所以有效,是因为在堆(Box
)中创建了一个拥有的错误(impl Error for Box
),并且std为Box
实现了Error
)
如果要删除具体类型,并且只使用trait的可用方法,可以使用impl trait
使用std:{error,fs};
fn foo(s:&str)->结果{
让result=fs::读取到字符串?;
好(结果)
}
fn条(s:&str)->结果{
让结果=匹配fs::读取到字符串{
Ok(x)=>x,
Err(x)=>返回Err(x),
};
好(结果)
}
fn main(){
println!(“{}”,foo(“foo.txt”).unwrap();
println!(“{}”,bar(“bar.txt”).unwrap();
}
虽然可以将具体类型std::io::Error
转换为dyn Error
,但不可能将其作为引用返回,因为“owned”值在函数末尾被删除/擦除/移除,这同样适用于字符串->&str
。Box
示例之所以有效,是因为在堆(Box
)中创建了一个拥有的错误(impl Error for Box
),并且std为Box
实现了Error
)
如果要删除具体类型,并且只使用trait的可用方法,可以使用impl trait
使用std:{error,fs};
fn foo(s:&str)->结果{
让result=fs::读取到字符串?;
好(结果)
}
fn条(s:&str)->结果{
让结果=匹配fs::读取到字符串{
Ok(x)=>x,
Err(x)=>返回Err(x),
};
好(结果)
}
fn main(){
println!(“{}”,foo(“foo.txt”).unwrap();
println!(“{}”,bar(“bar.txt”).unwrap();
}