在Rust中,当传播带有问号的错误时,对类型转换感到困惑?

ki0zmccv  于 2023-10-20  发布在  其他
关注(0)|答案(3)|浏览(105)

当我传播带问号的错误时,我发现不同类型的错误都能正常工作,代码如下所示:

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"))
}

编译器抱怨返回类型不匹配。直接返回和问号有什么区别?是否有任何隐式类型转换将与问号一起应用?谢谢你,谢谢

wsxa1bj1

wsxa1bj11#

是的,问号运算符(或ErrorPropagationExpression)确实内置了一个隐式类型转换:
当应用于Result<T,E>类型的值时,它会传播错误。如果值是Err(e),那么它将从封闭函数或闭包返回Err(From::from(e))。如果应用于Ok(x),那么它将展开值以评估x。
也就是说,Result上下文中的错误类型可以通过Into/From进行转换,类型转换隐式发生。

x6492ojm

x6492ojm2#

很简单,问号运算符?expands toreturn Err(From::from(err))
然而,你的最后一个例子没有显式地尝试从String转换为Car,因此出现了错误。在Rust中,转换不能隐式发生

myzjeezk

myzjeezk3#

Rust: The ? operator表示此示例代码:

File::create("foo.txt")?.write_all(b"Hello world!")

大致转化为:

match File::create("foo.txt") {
    Ok(t)  => t.write_all(b"Hello world!"),
    Err(e) => return Err(e.into()),
}

请注意,有一个.into()应用于错误,如果你修改你的代码如下:

fn f() -> Result<Car,Car> {
   Err(String::from("xxx").into())
}

然后编译器不再抱怨:该值被转换为Car

相关问题