【问题标题】:Error thrown citing match arms with incompatible types when pattern matching an Option模式匹配选项时引用具有不兼容类型的匹配臂时引发错误
【发布时间】:2017-08-27 08:25:20
【问题描述】:

我对 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 都是同一个枚举类型的一部分。谁能解释编译器对我的代码有什么问题?

【问题讨论】:

    标签: hashmap rust pattern-matching optional


    【解决方案1】:

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

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

    表达式*count += 1 的计算结果为()(在Rust 中称为“unit”,在许多其他语言中称为“void”)。另一方面,表达式map.insert(a, 0) 返回Option&lt;V&gt;,其中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 中有更详细的解释。简而言之:借用检查器不够聪明,无法识别出你的代码是好的,因此你应该使用超级好的entry-API

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

    【讨论】:

    • 感谢您的完美工作!我会更多地研究entry API,它看起来非常有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多