为什么在我的 match 语句中用大括号包裹 None 会使下面的 Rust 代码起作用?

use*_*535 1 rust

我有一个非常简单的 Rust 程序,其中有一个 hashmap<String, Vec> ,如果键不存在,我想插入一个新数组,如果键存在,则推送到现有数组。但是,如果我删除 None 周围的大括号(如代码 2 中所示),则会出现以下错误。这是怎么回事?代码 1 按预期工作,但我只是不明白为什么。

error[E0308]: `match` arms have incompatible types
  --> src/main.rs:97:20
   |
94 | /     match get_option {
95 | |         None => map.insert(str_check, vec![String::from("inserted!")]),
   | |                 ------------------------------------------------------ this is found to be of type `Option<Vec<String>>`
96 | |         
97 | |         Some(v) => v.push(String::from("Chris")),
   | |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<Vec<String>>`, found `()`
98 | |     }
   | |_____- `match` arms have incompatible types
   |
   = note:   expected enum `Option<Vec<String>>`
           found unit type `()`
note: method `push` modifies its receiver in-place
  --> src/main.rs:97:22
   |
97 |         Some(v) => v.push(String::from("Chris")),
   |                      ^^^^ this call modifies `v` in-place

For more information about this error, try `rustc --explain E0308`.
Run Code Online (Sandbox Code Playgroud)

代码 1。

use std::collections::HashMap;

fn main() {
    let mut map: HashMap<String, Vec<String>> = HashMap::new();

    map.insert(String::from("first"), Vec::new());

    let str_check = String::from("second");
    let get_option = map.get_mut(&str_check);

    match get_option {
        None => {
            map.insert(str_check, vec![String::from("inserted!")]);
        }
        Some(v) => v.push(String::from("Chris")),
    }

    println!("{:?}", map);
}
Run Code Online (Sandbox Code Playgroud)

代码2:

use std::collections::HashMap;

fn main() {
    let mut map: HashMap<String, Vec<String>> = HashMap::new();

    map.insert(String::from("first"), Vec::new());

    let str_check = String::from("second");
    let get_option = map.get_mut(&str_check);

    match get_option {
        None => map.insert(str_check, vec![String::from("inserted!")]),
        Some(v) => v.push(String::from("Chris")),
    }

    println!("{:?}", map);
}
Run Code Online (Sandbox Code Playgroud)

Sil*_*olo 6

和牙套没有关系。其实就是分号。

map.insert(key, value)
Run Code Online (Sandbox Code Playgroud)

这是一个返回类型值的表达式Option<V>,如 的文档HashMap::insert中所示。

{
  map.insert(key, value)
}
Run Code Online (Sandbox Code Playgroud)

这是完全等价的。宏可以在语法上区分两者,但在语义上它们是相同的。它仍然是一个返回Option<V>.

{
  map.insert(key, value);
}
Run Code Online (Sandbox Code Playgroud)

这样就返回了()。我们针对其副作用执行一个表达式,然后丢弃结果。块中的尾随分号就像我们在()后面添加分号一样。所以上面是简写

{
  map.insert(key, value);
  ()
}
Run Code Online (Sandbox Code Playgroud)

至于为什么需要(),这是因为您的其他分支调用Vec::push,它返回(),因此为了使您的两个分支匹配,它们必须都返回()