Rust 为什么普通匹配表达式会编译,而map#u err调用不会';T
使用rustc 1.30.1和reqwest 0.9.5 我有一个调用其他几个函数的函数,这些函数可能返回不同类型的错误,特别是Rust 为什么普通匹配表达式会编译,而map#u err调用不会';T,rust,Rust,使用rustc 1.30.1和reqwest 0.9.5 我有一个调用其他几个函数的函数,这些函数可能返回不同类型的错误,特别是std::io::Error和reqwest::Error 要将这些信息传播给调用者,最简单的解决方案似乎是将它们放在框中,这样可以方便地实现From特征以及Error特征本身。像这样: fn fetch_input() -> Result<String, Box<dyn Error>> { ... let session_
std::io::Error
和reqwest::Error
要将这些信息传播给调用者,最简单的解决方案似乎是将它们放在框中
,这样可以方便地实现From
特征以及Error
特征本身。像这样:
fn fetch_input() -> Result<String, Box<dyn Error>> {
...
let session_cookie = load_session_cookie()?; // Returns Result<String, io::Error>
let text: Result<String, reqwest::Error> = ...;
text.map_err(Box::new) // Compile error on this line
}
请注意,这与标准库中的map\u err
实现的主体相同。那么为什么我的map\u err
调用没有通过类型检查器呢?不用说
我还想知道错误消息中的
静态生存期是从哪里来的。如果结果是不相关的,我可能会为它提出一个不同的问题。Box::new
做一件事,而且只做一件事:获取一个reqwest::Error
并将其放入框中
表达式Box::new(e)
做两件事:调用Box::new
,它接受reqwest::Error
并将其放入框中,然后将框
强制放入框中
强制类型是Rust通常试图避免的事情<代码>框
→ <代码>框
(和其他类似的直接指针→指针强制)是一个例外。特别是,锈蚀不会将结果
强制为结果
至于你的旁白:因为dyn Trait
总是需要一个相关的生命周期。当您将dyn Trait
放在一个框中时,它被隐式地假定为静态的
。当你有一个dyn特征时,它被假定为是一个,你的旁题请看。text.map\u err(From::From)
或text.map\u err(| e | From::From(Box::new(e))
不要问我从来没有完全理解过。锈迹会迫使结果
变成结果
。试试看;这是一种标准的非尺寸强制。错误的原因更为微妙——这基本上是类型推断算法的一个缺点。下面是一个演示强制的游乐场链接:@SvenMarnach不,不是。该代码没有演示您认为它演示的内容。您犯了与OP完全相同的错误:您是对的–我的代码中的强制仅适用于框,并且Result
未实现importeunsized
。谢谢,回答得很好。我想知道Rust到底什么时候会和不会做这样的强迫,并找到了其中的全部细节。我最初问题的答案来自这样一个事实:将Box::new
作为函数传递不会创建强制站点。
error[E0308]: mismatched types
--> src/main.rs:26:5
|
16 | fn fetch_input() -> Result<String, Box<dyn Error>> {
| ------------------------------ expected `std::result::Result<std::string::String, std::boxed::Box<(dyn std::error::Error + 'static)>>` because of return type
...
26 | text.map_err(Box::new)
| ^^^^^^^^^^^^^^^^^^^^^^ expected trait std::error::Error, found struct `reqwest::Error`
|
= note: expected type `std::result::Result<_, std::boxed::Box<(dyn std::error::Error + 'static)>>`
found type `std::result::Result<_, std::boxed::Box<reqwest::Error>>`
match text {
Ok(t) => Ok(t),
Err(e) => Err(Box::new(e)),
}