How can I pattern match against an Option?

后端 未结 4 1033
臣服心动
臣服心动 2021-01-01 10:13

I can straight-forwardly match a String in Rust:

let a = \"hello\".to_string();

match &a[..] {
    \"hello\" => {
        println!(\"Mat         


        
4条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-01 10:58

    Look at this.

    You cannot match on std::String, as you've found, only on &str. Nested pattern matches work, so if you can match on &str, you can match on Option<&str>, but still not on Option.

    In the working example, you turned the std::String into a &str by doing &a[..]. If you want to match on a Option, you have to do the same thing.

    One way is to use nested matches:

    match a {
        Some(ref s) => match &s[..] {
            "hello" => /* ... */,
            _ => /* ... */,
        },
        _ => /* ... */,
    }
    

    But then you have to duplicate the "otherwise" code if it's the same, and it's generally not as nice.

    Instead, you can turn the Option into an Option<&str> and match on this, using the map function. However, map consumes the value it is called on, moving it into the mapping function. This is a problem because you want to reference the string, and you can't do that if you have moved it into the mapping function. You first need to turn the Option into a Option<&String> and map on that.

    Thus you end up with a.as_ref().map(|s| /* s is type &String */ &s[..]). You can then match on that.

    match os.as_ref().map(|s| &s[..]) {
        Some("hello") => println!("It's 'hello'"),
        // Leave out this branch if you want to treat other strings and None the same.
        Some(_) => println!("It's some other string"),
        _ => println!("It's nothing"),
    }
    

提交回复
热议问题