我正在创建一个简单的程序,它一次读取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 回答
它说的是表达式返回
Option<u64>
,其中()
(单位值,实际上是"nothing")是预期的 .应该返回单位值的表达式是
match
. 封闭的for
返回()
(即期望没有值返回),所以match
也不会返回任何值 . 但它的两个分支正在返回insert
的结果,一个Option
.告诉Rust丢弃返回值的方法是添加一个
;
,就像这样;错误消息的格式为
expected X, found Y (expected A, found B)
.X
和Y
是完全不匹配的类型,然后,在括号中,A
和B
聚焦于出现第一个不匹配的类型部分 . 当涉及泛型的类型不匹配时,这尤其有用 . 这是一个(人为的)例子:这会出现以下错误:
此处,
a
变量的类型与type_mismatch
上x
参数的类型不匹配 . 注意它们的类型是如何相似的,但两种情况下的区别在于Mutex
的类型参数 . 编译器专注于这种差异,因此您可以更轻松地发现它 .随着您对所使用的库越来越熟悉,有时只需阅读有针对性的类型就足以帮助您找出问题所在 .
使用上面的代码,
match
表达式的类型为Option<u64>
(因为所有分支的类型都为Option<u64>
) . 一个for
循环体必须以一个语句终止,所以简单地放一个;
来使match
成为一个语句 .Look here for more details