我的原始代码是:
const DNA: [char; 4] = ['A', 'C', 'G', 'T'];
...
let mut map: HashMap<char, usize> = HashMap::new();
/* initialize the hashmap */
for d in DNA.iter() {
map.insert(*d, 0);
}
代码已经编译好了,然后我想用for_each替换for循环:
DNA.iter().for_each(|d| map.insert(*d, 0));
编译错误:
error[E0308]: mismatched types
--> src/lib.rs:26:29
|
26 | DNA.iter().for_each(|d| map.insert(*d, 0));
| ^^^^^^^^^^^^^^^^^ expected `()`, found enum `Option`
|
= note: expected unit type `()`
found enum `Option<usize>`
看起来for_each和for并不完全等价,为什么for_each不直接忽略map.insert()
的返回值呢?
3条答案
按热度按时间bogh5gae1#
为什么for_each不直接忽略map.insert()的返回值呢?
因为Rust语法根本不是这样工作的。
1.每个函数都有一个返回类型,省略它并不意味着“没有返回值”,这是
-> ()
的语法糖,即返回类型为“unit”。1.显式的
return map.insert(*d, 0);
和块末尾没有分号的简写map.insert(*d, 0)
都是return语句,它们是显式的“在这里返回”,而不是可选的“如果有意义,可能返回一个值”。因此,您当前尝试提供一个
Option<V>
,而函数签名需要一个()
,这就是为什么会出现所示的错误。因此,您必须调整闭包,使其不返回该值(或者更具体地说,返回单位类型
()
):注意第一个版本返回的值与函数签名匹配,第二个版本只是语法上的糖衣炮弹,可以省略返回值
()
。xcitsw882#
其他的答案解释了问题是什么,以及解决方案是什么(使返回类型为
()
),但是,没有一个答案提到标准库中有一个函数,在序言中,这个函数就是这样做的:它是drop
。实际上,drop: fn(T) -> ()
是任何类型的T
,它没有做任何其他事情(它的定义就是fn drop<T>(_: T) {}
)。为了解决你的问题,你可以
qaxu7uf23#
以上是
std::iter::for_each
的函数签名。注意,约束F: FnMut(Self::Item)
意味着它只能用回调函数调用,该回调函数以Self::Item
作为输入,并且不返回任何值。如果您必须使用for_each
执行此任务,则可以选择附加分号;
,使闭包不返回任何值。尽管这与for ... in
版本的标点符号数量几乎相同。rust eclipse 文件上的
std::iter::for_each