16.枚举中的option和result.rs

fn test_option() {
    //Option 是 Rust 标准库中的枚举类,这个类用于填补 Rust 不支持 null 引用的空白
    /*
        enum Option<T> {
            Some(T),
            None,
        }
    */
    let opt = Option::Some("Option_Some_str");
    match opt {
        Option::Some(something) => {
            println!("{}", something);
        }
        Option::None => {
            println!("opt is nothing");
        }
    }

    //如何将option的值取出来?
    {
        //方法1
        fn get_option_value() -> Result<i32, String> {
            let t = Option::Some(100).ok_or("111")?;
            println!("get the value successfully - {}", t);
            Ok(0)
        }
        let _ = get_option_value();

        方法2
        let t = Some(112);
        if let Some(v) = t {
            println!("v -- {}", v);
        }

        方法3
        let t = Some(112);
        let t2 = t.unwrap();
        println!("v -- {}", t2);
    }

    //如果你的变量刚开始是空值,你体谅一下编译器,它怎么知道值不为空的时候变量是什么类型的呢?所以初始值为空的 Option 必须明确类型
    let opt: Option<&str> = Option::None;
    match opt {
        Option::Some(something) => {
            println!("{}", something);
        }
        Option::None => {
            println!("opt is nothing");
        }
    }

    //由于 Option 是 Rust 编译器默认引入的,在使用时可以省略 Option:: 直接写 None 或者 Some()
    //Option 是一种特殊的枚举类,它可以含值分支选择
    let t = Some(64);
    match t {
        Some(64) => println!("Yes64"),
        Some(72) => println!("Yes72"),
        _ => println!("No"),
    }

    //普通match
    let i = 0;
    match i {
        0 => println!("zero"),
        _ => {}
    }

    //常用函数: is_some,is_none,contains,as_ref,expect,unwrap,unwrap_or,map,map_or,ok_or,and_then...

    //ok_or可以在值为None的时候返回一个Result::Err(E),值为Some(T)的时候返回Ok(T)
    let t: Option<i32> = Option::None;
    let _errr = t.ok_or("123");
    println!("_errr--->{:?}", _errr);

    let t: Option<i32> = Option::Some(128);
    let _errr = t.ok_or("123");
    println!("_errr--->{:?}", _errr);

    //这个组合算子可用于简单映射Some -> Some 和 None -> None 的情况。多个不同的 map() 调用可以更灵活地链式连接在一起。
    let op_map = t.map(|mut param| {
        param = 100;
        param
    });
    println!("op_map--->{:?}", op_map);

    t.ok_or(123);
}

fn test_result() {
    //常用函数:  is_ok,is_err,ok,err,as_ref,as_mut,map,map_or,map_err,and_then,or,unwrap_or,,,,,,,,,,
    fn test_result_in() -> Result<i32, String> {
        println!("---------------------------");

        //return Err(String::from("123"));
        return Ok(123);
    }

    //如何将Result的值取出来?
    fn get_result_value() -> Result<i32, i32> {
        let t: Result<i32, i32> = Ok(1000);
        let t2 = t?;
        println!("get the value successfully - {}", t2);
        Ok(0)
    }
    let _ = get_result_value();

    let ret = test_result_in();
    //map() 以链式调用的方式来简化 match 语句。然而,在返回类型是 Option<T> 的函数中使用 map() 会导致出现嵌套形式 Option<Option<T>>。多层链式调用也会变得混乱。所以有必要引入 and_then()
    let ret2 = ret.and_then(|mut param| {
        param = 1000;
        Ok(param)
    });

    let ret3 = ret2.map_err(|e| e.to_string());
    println!("{:?}", ret3);

    ret3.ok();
}

//看一个例子
fn double_first(vec: Vec<&str>) -> Result<i32, String> {
    vec.first()
        // 若值存在则将 `Option` 转换成 `Result`。
        // 否则提供一个包含该字符串(`String`) 的 `Err`。
        .ok_or("Please use a vector with at least one element.".to_owned())
        // 回想一下,`parse` 返回一个 `Result<T, ParseIntError>`。
        .and_then(|s| {
            s.parse::<i32>()
                // 映射任意错误 `parse` 产生得到 `String`。
                // (原文:Map any errors `parse` yields to `String`.)
                .map_err(|e| e.to_string())
                // `Result<T, String>` 成为新的返回类型,
                // 我们可以给里面的数字扩大两倍。
                .map(|i| 2 * i)
        })
}

/*
简单的总结:

ok():检查Option是否为空,返回一个Result值,不为空就就是Ok(T)的枚举,为空就是Err(E)的枚举
调用者:Result
参数:空
返回值:Option或Result

ok_or():检查Option是否为空,返回一个Result值,不为空就就是Ok(T)的枚举,为空就是Err(E)的枚举
调用者:Option或Result
参数:错误信息
返回值:Result

map():可以处理Option和Result两种枚举,只处理Option::Some(T),None原样返回,Result只处理Ok(T),Err原样返回
调用者:Option或Result
参数:闭包函数
返回值:Option或Result

map_err():只处理Result里面的Err,
调用者:Result
参数:闭包函数
返回值:Result

and_then():和map函数及其类似,只不过返回值不同,map操作Option肯定返回的是Option,map操作Result肯定返回的是Result,and_then相当于给结果脱了一层衣服
调用者:Option或Result
参数:闭包函数
返回值:闭包返回值
*/

fn main() {
    test_option();
    test_result();

    let t = Some(123);
    let t2 = t.unwrap();

    let s: Result<i32, &str> = Ok(123);
    //let s: Result<i32, &str> = Err("123");
    let s2 = s.unwrap();
    println!("{}", s2);
}

猜你喜欢

转载自blog.csdn.net/liujiayu2/article/details/114387576