我有一个结构是一个API端点,所以我不能改变它的结构
struct Response {
error: Option<String>,
results: Vec<String>,
}
如果error
是Some
,那意味着它失败了服务器端。
我有一个返回结构的函数:
fn get_results() -> Result<Response, String> {
unimplemented!()
}
是否有可能匹配get_results
Result
错误,以及可选的Response.error
在同一个match
分支?
这是我的尝试:
fn example() {
let ret = get_results();
match ret.map(|resp| resp.error.map_or_else(|| Ok(resp.results), |e| Err(e))) {
Err(e) => {
println!("Error: {}", &e);
}
Ok(results) => {
//Handle results
}
}
}
但它失败了:
error[E0382]: use of moved value: `resp`
--> src/lib.rs:12:49
|
12 | match ret.map(|resp| resp.error.map_or_else(|| Ok(resp.results), |e| Err(e))) {
| ---------- ^^ ---- use occurs due to use in closure
| | |
| | value used here after move
| value moved here
|
= note: move occurs because `resp.error` has type `std::option::Option<std::string::String>`, which does not implement the `Copy` trait
您可以将响应转换为如下结果:
match resp.error {
Some(e) => Err(e),
None => Ok(resp.results),
}
您可以使用and_then
展平嵌套结果。放在一起,它给出了:
ret.and_then(|resp| match resp.error {
Some(e) => Err(e),
None => Ok(resp.results),
})
如果错误字段是公共的,您可以执行以下操作:
match resp {
Err(s) | Ok(Response { error: Some(s), .. }) => println!("Error: {}", s),
Ok(Response { error: None, results }) => println!("Responses: {:?}", results)
}
这表明Rust的匹配语句有多强大。