首页 文章

插入HashMap <&str,u64>时出现类型不匹配错误

提问于
浏览
2

我正在创建一个简单的程序,它一次读取stdin一行直到它到达文件的末尾,然后在输入中打印每个字母的频率(即:字符,实际上是技术上的Unicode字母) . The full source is on Github . 我正在使用rustc版本1.6.0和货物0.7.0

在程序中,我定义了一个 HashMap<&str, u64> 来存储统计信息,使用字母作为键,并将该字母的出现次数作为值 . 循环遍历每个字母时,我执行以下操作来存储统计信息:

for line in stdin.lock().lines() {
    let mut line = line.unwrap().as_str();

    // For each line, store it's character.
    for grapheme in UnicodeSegmentation::graphemes(line, true) {
        match counter.get(grapheme) {
            Some(v) => counter.insert(grapheme, v + 1),
            None => counter.insert(grapheme, 1)
        }
    }
}

(其中 grapheme is a reference to a string) .

我意识到这可能不是更新hashmap中计数器的最佳方法,但我相信它应该在技术上有效 - 毕竟我是一个完整的Rust n00b .

当我 cargo build 时,我得到:

expected `()`,
    found `core::option::Option<u64>`
(expected (),
    found enum `core::option::Option`) [E0308]
src/main.rs:18             match counter.get(grapheme) {
src/main.rs:19                 Some(v) => counter.insert(grapheme, v + 1),
src/main.rs:20                 None => counter.insert(grapheme, 1)
src/main.rs:21             }

...从查看E0308的文档,以及确切的错误消息,我理解编译器正在获得一种类型并期待另一种类型;但我不明白:

  • 我是否看到两个不匹配或一个,即:

  • core::option::Option<u64>core::option::Option 之间是否存在不匹配?

  • 有两个不匹配, ()core::option::Option<u64> 之间以及 ()core::option::Option 之间?

  • 别的什么?

  • 我没有编译器如何解释具有正确类型的东西(即:如何解决问题) .

2 回答

  • 4

    它说的是表达式返回 Option<u64> ,其中 () (单位值,实际上是"nothing")是预期的 .

    应该返回单位值的表达式是 match . 封闭的 for 返回 () (即期望没有值返回),所以 match 也不会返回任何值 . 但它的两个分支正在返回 insert 的结果,一个 Option .

    告诉Rust丢弃返回值的方法是添加一个 ; ,就像这样;

    match counter.get(grapheme) {
        Some(v) => counter.insert(grapheme, v + 1),
        None => counter.insert(grapheme, 1)
    }; //add a ; here
    

    错误消息的格式为 expected X, found Y (expected A, found B) . XY 是完全不匹配的类型,然后,在括号中, AB 聚焦于出现第一个不匹配的类型部分 . 当涉及泛型的类型不匹配时,这尤其有用 . 这是一个(人为的)例子:

    use std::sync::{Arc, Mutex};
    
    fn type_mismatch(x: Arc<Mutex<String>>) {}
    
    fn main() {
        let a = Arc::new(Mutex::new(0i32));
        type_mismatch(a);
    }
    

    这会出现以下错误:

    <anon>:7:19: 7:20 error: mismatched types:
     expected `alloc::arc::Arc<std::sync::mutex::Mutex<collections::string::String>>`,
        found `alloc::arc::Arc<std::sync::mutex::Mutex<i32>>`
    (expected struct `collections::string::String`,
        found i32) [E0308]
    <anon>:7     type_mismatch(a);
                               ^
    

    此处, a 变量的类型与 type_mismatchx 参数的类型不匹配 . 注意它们的类型是如何相似的,但两种情况下的区别在于 Mutex 的类型参数 . 编译器专注于这种差异,因此您可以更轻松地发现它 .

    随着您对所使用的库越来越熟悉,有时只需阅读有针对性的类型就足以帮助您找出问题所在 .

  • 3

    使用上面的代码, match 表达式的类型为 Option<u64> (因为所有分支的类型都为 Option<u64> ) . 一个 for 循环体必须以一个语句终止,所以简单地放一个 ; 来使 match 成为一个语句 .

    match counter.get(grapheme) {
        Some(v) => counter.insert(grapheme, v + 1),
        None => counter.insert(grapheme, 1)
    };
    

    Look here for more details

相关问题