使用 unwrap_or/unwrap_or_else 进行函数式转换的惯用方法

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

我有一种情况,我想通过

reqwest::header::HeaderValue

阅读一些标题

我正在这样做

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let url = "https://httpbin.org/get";
    let resp = reqwest::Client::new().get(url).send().await?;

    // read response headers
    // default if the header does not exist
    let resp_headers: &str = resp
        .headers()
        .get("content-length")
        .unwrap_or(&reqwest::header::HeaderValue::from_str("100").unwrap())
        .to_str()
        .unwrap_or("100");
    println!("{}", resp_headers);

    Ok(())
}

这看起来不符合习惯并且无法编译。寻找如何处理这样的场景,其中有几个必要的解包来处理并将类型转换为所需的最终结果。

rust error-handling unwrap
1个回答
0
投票

您可以使用命名块和let-else 语句。

let resp_headers: &str = 'block: {
    let Some(content_length) = resp.headers().get(reqwest::header::CONTENT_LENGTH) else {
        break 'block "100";
    };
    let Ok(content_length) = content_length.to_str() else {
        break 'block "100";
    };
    content_length
};

或者,如果您打算保持两个展开值相同,您可以使用

Option::and_then

let resp_headers: &str = resp
    .headers()
    .get(reqwest::header::CONTENT_LENGTH)
    .and_then(|content_length| content_length.to_str().ok())
    .unwrap_or("100");

或者您可以将其放入函数中并使用

?

fn read_content_length(resp: &reqwest::Response) -> Option<&str> {
    resp.headers()
        .get(reqwest::header::CONTENT_LENGTH)?
        .to_str()
        .ok()
}

let resp_headers: &str = read_content_length(&resp).unwrap_or("100");

但是专门针对

content-length
标头,有
Response::content_length

let resp_headers: u64 = resp.content_length().unwrap_or(100);
© www.soinside.com 2019 - 2024. All rights reserved.