For .. in .. vs iter().map of vec!

I've the below code that works fine:

let users = vec!("wrong@email", "");

for user in users {
            match template.clone().to(user).build() {
                   Err(e) => println!("error: {:?} in email: {}", e, user),
                   Ok(e) => {
                         match mailer.send(e.into()) {
                                 Err(e) => println!("error: {:?} in emailing: {}", e, user),
                                 Ok(r) => println!("Emailing: {}, {:?}", user, r.message)

I'm trying to replace the

for user in users { 



But found that the iter().map is returning user as &&str which is not accepted fortemplate.clone().to(user).build()

How can I fix it?

The direct translation of for user in users {} is users.into_iter().for_each(|user| {}).
You could also deref user:


You might have to borrow it again (&**user), I'm not sure.


    match template.clone().to(*user).build() {}


     match template.clone().to(user).build() {}

Had been worked.

But in both cases I got the below warning:

warning: unused `std::iter::Map` that must be used
  --> src/
30 | /                         users.iter().map(|user| {
31 | |                             match template.clone().to(*user).build() {
32 | |                                 Err(e) => println!("error: {:?} in email: {}", e, user),
33 | |                                 Ok(e) => {
...  |
40 | |                         }
41 | |                         );
   | |__________________________^
   = note: #[warn(unused_must_use)] on by default
   = note: iterators are lazy and do nothing unless consumed

Iterators in Rust are lazy, they only do something when you ask them to.
One way is to use for_each.
map is probably not doing what you expect, in this case the entire iterator is created but never "executed".


Sorry if this is a silly Rust newbie question but why would one want to replace something short, sweet simple and obvious:

for user in users 

With something longer, more complex and obscure?


For some iterators using the for_each combinator will result in more efficient code. For example, the Chain and Flatten iterator combintors can be made more efficient.


While true, this is the kind of "optimization" that is heavily context-dependent and can easily turn into a pessimization if over-generalized. If you're using for_each for this kind of optimization advantage, you should definitely be profiling your code and therefore you'll know whether it makes a difference or not.

Personally I have never found a use for for_each -- I'm glad it exists, but I find for i in foo to be more clear, and I've never run across one of those situations where a for loop is slower. But I don't write much perf-sensitive code.

To editorialize a bit, the tendency of some people in Rust to coalesce everything into a chain of iterator adapters reminds me of the tendency in Python to coalesce everything into a nested list comprehension. It feels smart and efficient, and I've done it myself on occasion, but it's possible to go too far. Sometimes a for loop should just be a for loop.


Note that for_each isn't going to be slower, because its default implementation does the same thing a for loop does: call next until it returns None.

That said, I agree that the above still doesn't mean you should default to using for_each over a normal for loop. Sure, if the body is trivial so the for_each looks fine, then go for it if you like how it looks. But if the body is big enough that it looks bad in a for_each, then it's probably complex enough that any optimization difference will be irrelevant anyway.


If the closure is large enough, it may fall foul of LLVM's inlining heuristics and incur function call overhead, while the loop body is "pre-inlined". Actually I really don't know, maybe that never happens in this case, but that's what I was thinking of, anyway.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.