模式匹配选项时引用类型不兼容的匹配臂引发错误

Fat*_*unk 5 hashmap pattern-matching optional rust

我对 Rust 相当陌生,无法解决这个令人困惑的错误。

我只是想匹配aOptionget函数返回的 a HashMap。如果返回一个值,我想增加它,否则我想向地图添加一个新元素。

这是代码:

let mut map = HashMap::new();
map.insert("a", 0);
let a = "a";
match map.get(&a) {
    Some(count) => *count += 1,
    None => map.insert(a, 0),
}
Run Code Online (Sandbox Code Playgroud)

由此产生的错误:

let mut map = HashMap::new();
map.insert("a", 0);
let a = "a";
match map.get(&a) {
    Some(count) => *count += 1,
    None => map.insert(a, 0),
}
Run Code Online (Sandbox Code Playgroud)

我真的不知道该编译器抱怨什么类型的约在这里,因为这两个SomeNone是同一枚举类型的两个组成部分。谁能解释编译器对我的代码有什么问题?

Luk*_*odt 4

编译器指的是匹配臂主体返回的值,而不是每个匹配臂的模式类型。

Some(count) => *count += 1,
None => map.insert(a, 0),
Run Code Online (Sandbox Code Playgroud)

该表达式的*count += 1计算结果为()(在 Rust 中称为“unit”,在许多其他语言中称为“void”)。map.insert(a, 0)另一方面,表达式返回 hash 映射的值Option<V>类型V(在您的情况下为整数)。突然间,错误消息确实有意义了:

Some(count) => *count += 1,
None => map.insert(a, 0),
Run Code Online (Sandbox Code Playgroud)

我想你甚至不想从match块中返回一些东西(记住:match块也是表达式,所以你可以从中返回一些东西)。要丢弃任何表达式的结果,可以将其转换为带有 的语句;。让我们试试这个:

match map.get(&a) {
    Some(count) => {
        *count += 1;
    }
    None => {
        map.insert(a, 0);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,每个匹配臂主体都是一个块(介于{和之间}),并且每个块包含一个语句。请注意,从技术上讲,我们不需要更改第一个匹配臂,因为*count += 1已经返回了(),但这样更一致。


但是一旦你测试了这个,就会显示另一个与借用相关的错误。这是一个众所周知的问题,这里有更详细的解释。简而言之:借用检查器不够聪明,无法识别您的代码是否正常,因此您应该使用超级好的entry-API

let map = HashMap::new();
map.insert("a", 0);
let a = "a";
*map.entry(&a).or_insert(0) += 1;
Run Code Online (Sandbox Code Playgroud)