You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Rust中match语句None分支加花括号可使代码正常运行?

为什么Rust中match分支去掉花括号会触发类型不匹配?

我写了个简单的Rust程序,用HashMap<String, Vec<String>>实现需求——指定key不存在时插入新Vec,存在就往对应Vec里push元素。但像Code2那样把None分支的花括号去掉后就报类型不匹配错误,Code1保留花括号却能正常运行,想知道原因。

错误信息

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`.

Code1(正常运行)

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);
}

Code2(报错)

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);
}

原因解析

Rust的match表达式要求所有分支返回的类型必须完全一致,花括号在这里直接改变了分支的返回值类型:

  1. 带花括号的分支(Code1):
    花括号包裹的是一个代码块,代码块的返回值由最后一行决定。如果最后一行是带分号的语句(比如Code1里的map.insert(...);),整个代码块会返回单元类型()。而Some分支里的v.push(...)方法本身返回的就是(),所以两个分支的返回类型都是(),符合match的要求,编译通过。

  2. 去掉花括号的分支(Code2):
    此时分支直接把map.insert(...)作为返回值,而HashMap::insert方法的返回类型是Option<Vec<String>>(key不存在时返回None,存在时返回旧值的Some)。但Some分支的v.push(...)返回的还是(),两个分支返回类型一个是Option<Vec<String>>,一个是(),类型不兼容,因此触发E0308类型不匹配错误。

如果想去掉花括号也正常运行,你可以把None分支的返回值强制转成(),比如用花括号包裹并加分号(直接保留花括号其实更清晰):

None => { map.insert(str_check, vec![String::from("inserted!")]); },

内容的提问来源于stack exchange,提问作者user125535

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 14:25:28