[英]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:
但我不明白:
core::option::Option<u64>
and core::option::Option
? core::option::Option<u64>
和core::option::Option
之间是不匹配的? ()
and core::option::Option<u64>
and between ()
and core::option::Option
? ()
和core::option::Option<u64>
之间以及()
和core::option::Option
? 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. X
和Y
是完全不匹配的类型,然后,在括号中, A
和B
侧重于出现第一个不匹配的类型部分。 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)
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.