如何优化 Rust 中的多重 unwrap 代码语句

huangapple go评论89阅读模式
英文:

how to optimize the multi unwrap code statement in rust

问题

我正在学习使用Rust v1.65.0 发送HTTP请求。现在我有一个Rust代码块如下:

pub async fn get_queue_cv() {
    let client = Client::new();
    let url_path = "/cv/gen/v1/list";
    let url = format!("{}{}", get_app_config("cv.cv_api_url"), url_path);
    let response = client
        .post(url)
        .headers(construct_headers())
        .body("{}")
        .send()
        .await;
    match response {
        Ok(r) => {
            let r: serde_json::Value = r.json().await.unwrap();
            match r.get("result") {
                Some(_) => {},
                None => {},
            }
            let result: &serde_json::Value = r.get("result").unwrap();
            let first_element = result.get(0).unwrap();
            let queue_record: CvGen = serde_json::from_value(first_element.clone()).unwrap();
            let tpl_resp = get_template(queue_record);
            tpl_resp.await;
        }
        Err(e) => println!("Error: {}", e),
    }
}

这段代码工作正常,但有时当服务器返回空结果时,unwrap 会导致 panic。现在我想处理 unwrap 失败的情况,我尝试使用 match,但现在我发现使用 match 会使代码嵌套层级过多,使代码变得难看。我只想简单地处理 unwrap 失败的情况。我尝试过 unwrap_or_else,但不知道如何定义 else 条件。我应该怎么做来更好地处理这个 unwrap

英文:

I am learning to use rust v1.65.0 to send a http request. Now I have a rust code block like this:

pub async fn get_queue_cv() {
    let client = Client::new();
    let url_path = "/cv/gen/v1/list";
    let url = format!("{}{}", get_app_config("cv.cv_api_url"), url_path);
    let response = client
        .post(url)
        .headers(construct_headers())
        .body("{}")
        .send()
        .await;
    match response {
        Ok(r) => {
            let r: serde_json::Value = r.json().await.unwrap();
            match r.get("result") {
                Some(_) => {},
                None => {},
            }
            let result: &serde_json::Value = r.get("result").unwrap();
            let first_element = result.get(0).unwrap();
            let queue_record: CvGen = serde_json::from_value(first_element.clone()).unwrap();
            let tpl_resp = get_template(queue_record);
            tpl_resp.await;
        }
        Err(e) => println!("Error: {}", e),
    }
}

This code works fine, but sometimes when the server return null results, the unwrap will going o panic. Now I want to handle the unwrap failed situation, I am tried to use match, but now I found using match make the code has too much nested level and maket the code ugly. what I want just simplely return if any of unwrap failed. I have tried unwrap_or_else but I di d not know how to define the else condition. what should I do to handle this unwrap with a better way?

答案1

得分: 1

你可以尝试使用Option的以下方法来实现"Maybe" monad的方式:

let response = r.get("result")
  .map(|x| x.get(0))
  .map(|x| serde_json::from_value(x.clone()))
  .map(|x| get_template(x));
match response {
  Some(awaiter) => awaiter.await,
  None => // TODO: your implementation
}
英文:

You can try a "Maybe" monad approach via following methods of an Option:

let responce = r.get("result")
  .map(|x| x.get(0))
  .map(|x| serde_json::from_value(x.clone()))
  .map(|x| get_template(x));
match responce {
  Some(awaiter) => awaiter.await
  None => // TODO: your implementation
}

huangapple
  • 本文由 发表于 2023年5月28日 01:32:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76348180.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定