rust 不了解HashMap.entry()的匹配函数

7rfyedvj  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(181)

我刚开始学习Rust。entry方法是一个Entry枚举,可以通过match函数访问。但是我不明白为什么它不能编译,而且会死机。有人能解释一下我理解错了什么吗?

let mut scores: HashMap<String, u32> = HashMap::new();

scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);

let a = 10;
match scores.entry("poneyland".to_string()) {
    Occupied(o) => o.remove_entry(),
    Vacant(o) =>  o.insert(37),
}
goucqfw6

goucqfw61#

但我不明白为什么它不能编译,而且会死机。
它不能同时编译失败和死机,因为死机是一种运行时行为。无论哪种方式,当出现错误时,发布它通常是一个好主意,因为这会使诊断更容易,特别是在Rust中,通常会有非常有用的错误消息。
在本例中,编译错误会告诉您确切的内容:

error[E0308]: `match` arms have incompatible types
  --> src/main.rs:15:22
   |
13 | /     match scores.entry("poneyland".to_string()) {
14 | |         Occupied(o) => o.remove_entry(),
   | |                        ---------------- this is found to be of type `(String, u32)`
15 | |         Vacant(o) => o.insert(37),
   | |                      ^^^^^^^^^^^^ expected tuple, found `&mut u32`
16 | |     }
   | |_____- `match` arms have incompatible types
   |
   = note:          expected tuple `(String, u32)`
           found mutable reference `&mut u32`

您几乎只需要阅读消息,可能还需要阅读扩展的文档。
它归结为一个rust match是一个 * 表达式 *,意味着它有一个特定类型的值,意味着 * 所有arm必须有相同类型的值 *(或兼容类型,例如!)。
在这里,正如编译器错误告诉你的,在一个分支中,你调用remove_entry,它返回一个元组(key,value),而在另一个分支中,你调用insert,它返回一个对插入值的可变引用。
这些类型显然不兼容。
解决此问题的最简单方法是使它们兼容,方法是...完全抑制结果,因为您不使用它们:将arm表达式转换为arm blocks,并使用;终止表达式。这会将表达式转换为语句,并隐藏其值,隐式返回()

match scores.entry("poneyland".to_string()) {
        Occupied(o) => {
            o.remove_entry();
        }
        Vacant(o) => {
            o.insert(37);
        }
    }

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1b885daa2a4eaa6d9d7c366753f6c2aa

相关问题