我只是学习生锈,正在开展一项简单的/ r / dailyprogrammer任务。这是一些代码:
type ToDoList = HashMap<String, bool>;
fn print(list: &ToDoList) {
let mut max_len: usize = 0;
for (item, _) in list.iter() {
max_len = max(max_len, item.len());
}
let end = format!("+---{}-+",
iter::repeat("-").take(max_len).collect::<String>());
println!("{}", end);
for (item, done) in list.iter() {
let line = format!("| {0} {1}{2} |",
if done {"☑"} else {"☐"},
item,
iter::repeat("-")
.take(max_len - item.len())
.collect::<String>()
);
println!("{:?}", (item, done));
}
println!("{}", end);
}
我从rustc收到此错误:
error: type mismatch resolving `<std::collections::hash::map::Iter<'_,
collections::string::String, bool> as core::iter::Iterator>::Item ==
(_, bool)`: expected &-ptr,
found bool [E0271]
todolist.rs:19 for (item, done) in list.iter() {
todolist.rs:20 let line = format!("| {0} {1}{2} |",
todolist.rs:21 if done {"☑"} else {"☐"},
todolist.rs:22 item,
todolist.rs:23 iter::repeat("-")
todolist.rs:24 .take(max_len - item.len())
...
todolist.rs:24:21: 24:31 error: the type of this value must be known in this context
todolist.rs:24 .take(max_len - item.len())
^~~~~~~~~~ note: in expansion of format_args! <std macros>:2:26: 2:57 note: expansion site <std
macros>:1:1: 2:61 note: in expansion of format!
todolist.rs:20:14: 26:4 note: expansion site error: aborting due to 2 previous errors
似乎这两个问题都与同一个问题有关,以某种方式调用list.iter()
试图给我一个(_, String, bool)
而不是(String, bool)
的元组。为什么会这样?
答案 0 :(得分:7)
错误消息不是很易读。发生的事情是done
的类型为&bool
,因为您是以非拥有方式进行迭代。
类型不匹配解析
<std::collections::hash::map::Iter<'_, collections::string::String, bool> as core::iter::Iterator>::Item == (_, bool)
:
基本上,您需要检查std::collections::hash::map::Iter::Item
的实际类型。正如您在文档中看到的那样,它是(&'a K, &'a V)
。
更改
for (item, done) in list.iter() {
到
for (item, &done) in list.iter() {
将解决您的问题。
造成这种混乱的原因是Rust的类型推断。由于您使用done
作为if
的参数,因此Rust知道它需要是bool
类型的事实。所以它从那里倒退到done
- 绑定的赋值,直到找到其他具体类型。在其他语言中,它可能是另一种方式,并且错误将发生在if条件中。
作为旁注,在您的第一次迭代for (item, _) in list.iter() {
中,您只对HashMap
的键感兴趣。您可以使用for item in list.keys()
来获得更简洁的循环。
答案 1 :(得分:2)
似乎这两个都与同一个问题有关,以某种方式调用list.iter()试图给我一个元组(_,String,bool)而不是(String,bool)。为什么会这样?
你是对的,两者都与原始错误有关,但错误是错误的:
(_, bool)`: expected &-ptr,
你得到一个(_, bool)
元组,而编译器希望看到一个引用(&_, &bool)
的元组。这个_
很可能是编译器消息中的String
(或&String
),所以这不是问题。
问题是您期望值,编译器需要引用,这源于iter()
返回引用<< / em>迭代的集合的底层元素,简单的解决方法是更改匹配方式:
for (item, &done) in &list {
}
从文档中可以看出:
impl<'a, K, V> Iterator for Iter<'a, K, V>
type Item = (&'a K, &'a V)
另一种方法是将done
绑定到&bool
,然后在使用前取消引用它:
for (item, done) in &list {
if *done { ... } else { ... }
}