匹配Result :: Err或Result :: Ok中的可选字段

问题描述 投票:1回答:2

我有一个结构是一个API端点,所以我不能改变它的结构

struct Response {
    error: Option<String>,
    results: Vec<String>,
}

如果errorSome,那意味着它失败了服务器端。

我有一个返回结构的函数:

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
rust mapping match
2个回答
3
投票

您可以将响应转换为如下结果:

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

2
投票

如果错误字段是公共的,您可以执行以下操作:

match resp {
    Err(s) | Ok(Response { error: Some(s), .. }) => println!("Error: {}", s),
    Ok(Response { error: None, results }) => println!("Responses: {:?}", results)
}

这表明Rust的匹配语句有多强大。

Playground of a simplified example

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.