简体   繁体   English

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

[英]Mismatched types error when inserting into a HashMap<&str, u64>

I am creating a simple program which reads stdin one line at a time until it reaches the end of the file, then prints the frequency of each letter (ie: character, actually technically Unicode Graphemes) in the input. 我正在创建一个简单的程序,它一次读取stdin一行直到它到达文件的末尾,然后在输入中打印每个字母的频率(即:字符,实际上是技术上的Unicode字母)。 The full source is on Github . 完整的资源来自Github I'm using rustc version 1.6.0 and cargo 0.7.0 我正在使用rustc版本1.6.0和货物0.7.0

In the program, I define a HashMap<&str, u64> to store the statistics, using the letter as the key and the number of occurrences of that letter as the value. 在程序中,我定义了一个HashMap<&str, u64>来存储统计信息,使用字母作为键,并将该字母的出现次数作为值。 While looping through each letter, I do the following to store the statistics: 循环遍历每个字母时,我执行以下操作来存储统计信息:

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

(where grapheme is a reference to a string ). (其中grapheme 是对字符串的引用 )。

I realize this might not be the best way to update the counters in the hashmap, but I believe it should technically work --- I am a total Rust n00b after all. 我意识到这可能不是更新hashmap中计数器的最佳方法,但我相信它应该在技术上有效 - 毕竟我是一个完整的Rust n00b。

When I cargo build , I get: 当我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             }

... from looking at the docs for E0308, and the exact error message, I understand the compiler is getting one type and expecting another; ...从查看E0308的文档,以及确切的错误消息,我理解编译器正在获得一种类型并期待另一种类型; but I don't understand: 但我不明白:

  • whether I'm seeing two mismatches or one, ie: 我是否看到两个不匹配或一个,即:
    • is there a mismatch between core::option::Option<u64> and core::option::Option ? core::option::Option<u64>core::option::Option之间是不匹配的?
    • are there two mismatches, between () and core::option::Option<u64> and between () and core::option::Option ? 两个不匹配,在()core::option::Option<u64>之间以及()core::option::Option
    • something else? 别的什么?
  • I don't understand how to tell Rust's compiler how to interpret things with the correct type (ie: what to do to fix the issue). 我不明白如何告诉Rust的编译器如何解释具有正确类型的东西(即:如何解决问题)。

It's saying that the expression is returning a Option<u64> where a () (the unit value, so practically "nothing") is expected. 它说表达式返回一个Option<u64> ,其中a () (单位值,实际上“无”)是预期的。

The expression that should return the unit value is the match . 应该返回单位值的表达式是match The enclosing for returns () (ie expects no value to return), so the match is expected to return nothing too. 封闭for回报()即没有预期要返回的值),所以match有望复出也没什么。 But its two branches are returning the result of the insert , an Option . 但它的两个分支返回insert的结果,一个Option

The way to tell Rust to discard the return value is to add a ; 告诉Rust丢弃返回值的方法是添加一个; , like this; , 像这样;

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

The error message is of the form expected X, found Y (expected A, found B) . 错误消息的格式为expected X, found Y (expected A, found B) X and Y are the complete mismatching types, then, in parentheses, A and B focus on the part of the type where the first mismatch appears. XY是完全不匹配的类型,然后,在括号中, AB侧重于出现第一个不匹配的类型部分。 This is particularly useful when the mismatch happens on types involving generics. 当涉及泛型的类型不匹配时,这尤其有用。 Here's a (contrived) example: 这是一个(人为的)例子:

use std::sync::{Arc, Mutex};

fn type_mismatch(x: Arc<Mutex<String>>) {}

fn main() {
    let a = Arc::new(Mutex::new(0i32));
    type_mismatch(a);
}

This gives the following error: 这会出现以下错误:

<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);
                           ^

Here, the type of the a variable doesn't match the type of the x parameter on type_mismatch . 这里, a变量的类型与type_mismatch上的x参数的类型不匹配。 Notice how their types are similar, but the difference is in the type parameter for Mutex in both cases. 注意它们的类型是如何相似的,但两种情况下的区别在于Mutex的类型参数。 The compiler focuses on this difference so you can spot it more easily. 编译器专注于这种差异,因此您可以更轻松地发现它。

As you get more familiar with the libraries you use, sometimes just reading the focused types will be enough to help you figure out what's wrong. 随着您对所使用的库越来越熟悉,有时只需阅读有针对性的类型就足以帮助您找出问题所在。

With your code above the match expression has type Option<u64> (because all the branches have type Option<u64> ). 使用上面的代码, match表达式的类型为Option<u64> (因为所有分支都具有类型Option<u64> )。 A for loop body must terminate with a statement so simply put a ; for循环体必须以语句终止,所以简单地放一个; to make that match a statement. 使该match成为一个陈述。

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

Look here for more details 在这里查看更多详情

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

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