当我传播带问号的错误时,我发现不同类型的错误都能正常工作,代码如下所示:
struct Car {
brand: String
}
impl From<String> for Car {
fn from(brand: String) -> Self {
Car { brand }
}
}
fn bar() -> Result<Car, String> {
Err(String::from("xxxx"))
}
fn f() -> Result<Car,Car> {
let c= bar()?;
Ok(Car::from(String::from("xxx")))
}
但当返回错误与不同的类型直接如下代码:
struct Car {
brand: String
}
impl From<String> for Car {
fn from(brand: String) -> Self {
Car { brand }
}
}
fn bar() -> Result<Car,String> {
Err(String::from("xxxx"))
}
fn f() -> Result<Car,Car> {
Err(String::from("xxx"))
}
编译器抱怨返回类型不匹配。直接返回和问号有什么区别?是否有任何隐式类型转换将与问号一起应用?谢谢你,谢谢
3条答案
按热度按时间wsxa1bj11#
是的,问号运算符(或
ErrorPropagationExpression
)确实内置了一个隐式类型转换:当应用于Result<T,E>类型的值时,它会传播错误。如果值是Err(e),那么它将从封闭函数或闭包返回Err(From::from(e))。如果应用于Ok(x),那么它将展开值以评估x。
也就是说,
Result
上下文中的错误类型可以通过Into
/From
进行转换,类型转换隐式发生。x6492ojm2#
很简单,问号运算符
?
expands toreturn Err(From::from(err))
。然而,你的最后一个例子没有显式地尝试从
String
转换为Car
,因此出现了错误。在Rust中,转换不能隐式发生myzjeezk3#
Rust: The
?
operator表示此示例代码:大致转化为:
请注意,有一个
.into()
应用于错误,如果你修改你的代码如下:然后编译器不再抱怨:该值被转换为
Car
。