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

标签 hashmap rust pattern-matching optional

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

我只是想匹配Optionget函数返回的HashMap。如果返回值,我想增加它,如果没有,我想向 map 添加一个新元素。

这是代码:

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

产生的错误:

error[E0308]: match arms have incompatible types
  --> <anon>:7:5
   |
7  |       match map.get(&a) {
   |  _____^ starting here...
8  | |         Some(count) => *count += 1,
9  | |         None => map.insert(a, 0),
10 | |     }
   | |_____^ ...ending here: expected (), found enum `std::option::Option`
   |
   = note: expected type `()`
              found type `std::option::Option<{integer}>`
note: match arm with an incompatible type
  --> <anon>:9:17
   |
9  |         None => map.insert(a, 0),
   |                 ^^^^^^^^^^^^^^^^

我不太确定编译器在这里提示什么类型,因为SomeNone都是同一个枚举类型的一部分。谁能解释我的代码对编译器有什么影响?

最佳答案

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

Some(count) => *count += 1,
None => map.insert(a, 0),

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

= note: expected type `()`
= note:    found type `std::option::Option<{integer}>`

我想您甚至不想从match块返回某些内容(请记住:match块也是表达式,因此您可以从中返回一些内容)。要丢弃任何表达式的结果,可以将其转换为带有;的语句。让我们尝试一下:
match map.get(&a) {
    Some(count) => {
        *count += 1;
    }
    None => {
        map.insert(a, 0);
    }
}

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

但是一旦您对此进行测试,将显示与借用相关的另一个错误。这是一个众所周知的问题,并在here中进行了更详细的说明。简而言之:借阅检查器不够聪明,无法识别您的代码很好,因此您应该使用 super 漂亮的 entry -API:
let map = HashMap::new();
map.insert("a", 0);
let a = "a";
*map.entry(&a).or_insert(0) += 1;

关于hashmap - 模式匹配选项时,引用类型不兼容的匹配臂引发错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65415739/

相关文章:

java - "Cannot create generic array of .."- 如何创建 Map<String, Object> 的数组?

java - 从 HashMap 返回一个元素

struct - Rust struct : borrowing, 生命周期内的结构,泛型类型和更多的完全困惑

rust - 我应该在 64 位机器上使用 i32 还是 i64?

generics - Rust 中相互依赖的通用特征

scala - 在子类中扩展 Scala 模式匹配,同时保持复杂性

functional-programming - 详尽的模式

java - HashMap 和 Hashcode

关于哈希表的 C++ 问题

java - 如何使用 ListObjectsV2Request 上的前缀或分隔符过滤 AWS 中的键?