为什么for_each不能代替代码中的for循环?

yuw*_*wen 3 rust

我原来的代码是:

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);
}
Run Code Online (Sandbox Code Playgroud)

代码已编译。然后我想用 for_each 替换 for 循环:

DNA.iter().for_each(|d| map.insert(*d, 0));
Run Code Online (Sandbox Code Playgroud)

编译错误:

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>`                
Run Code Online (Sandbox Code Playgroud)

看来for_each和for并不完全等价?为什么 for_each 不忽略 的返回值map.insert()

Luc*_* S. 5

为什么 for_each 不忽略 map.insert() 的返回值?

因为 Rust 语法根本就不能那样工作。

  1. 每个函数都有一个返回类型,省略它并不意味着“没有返回值”。这是 的语法糖-> (),即“unit”的返回类型。
  2. 块末尾没有分号的显式return map.insert(*d, 0);和简写都是 return 语句。map.insert(*d, 0)它们明确地“在此处返回”,而不是可选的“如果有意义的话可能返回一个值”。

因此,您当前正在尝试提供Option<V>函数签名需要 a 的位置(),这就是您收到所示错误的原因。

因此,您必须调整闭包以不返回该值(或更具体地说,返回单位类型()):

// the explicit version
DNA.iter().for_each(|d| {
  map.insert(*d, 0);
  ()
});
// the more idiomatic, shorter equivalent
DNA.iter().for_each(|d| { map.insert(*d, 0); });
Run Code Online (Sandbox Code Playgroud)

请注意第一个版本如何返回与函数签名匹配的值。第二个版本只是语法糖,您可以省略返回值().