Rust链式调用

关于链式调用我在很早之前写PHP的时候就接触过,今天说说关于Rust特有的链式调用。

RustResultOption是专门用来处理错误相关的类型,它们提供了像and_then, map_err等方法可以进行链式调用,且其中又包含了错误信息可以做到链式调用的同时灵活的进行错误处理。

下面是一段相关代码:

type MyResult<T> = Result<T, Box<dyn std::error::Error>>;

fn get_page(_url: &str) -> MyResult<String> {
    // Ok("Hello".into())
    // 第三方库抛出错误,错误信息可以用map_err格式化。
    // return get_http_client(url)?
    Err("".into())
}

fn find_str(_text: &str) -> Option<String> {
    Some("".into())
    // None
}

fn main() -> MyResult<()> {
    let url = "http://www.bstaint.net";
    /* python 3.8 code
    try:
        if text := get_page("http://www.bstaint.net") != "":
            if verify := find_str(text) != None:
                print("check url finish")
    except Exception as e:
        print(e) 
    */

    let verify = get_page(url).ok()
        .and_then(|text| find_str(&text))
        .unwrap();

    // 将get_page错误信息抛给上层调用者
    // let verify = Ok(get_page(url)?)
    let verify = get_page(url)
        .map_err(|_| format!("Cant't get_page url: {}", url))
        .and_then(|text| find_str(&text).ok_or(format!("Cant't find_str: {}", text)))
        .unwrap();

    println!("check url finish: {}", url);
        // .and_then(|_| Ok(println!("check url finish: {}", url)))
        // .map_err(|e| eprintln!("{}", e));

    Ok(())
}

我可以使用?将必要的错误抛给上层也可以and_then串联一起处理,使用map_err可以将第三方库的错误格式化。

而Python不使用Walrus运算符还得多写几行。

转载请注明: 本文《Rust链式调用》来源于bstaint的博客

没有评论: