繁体   English   中英

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

[英]Error thrown citing match arms with incompatible types when pattern matching an Option

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

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

这是代码:

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)表达式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已经返回() ,但这样更一致。


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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM