# How to Fix Type Mismatch in a Function？

Here I use `for_each` and `for` to process, what are the differences between these two ways of processing? `for_each` passes a tuple, but I think this does not conflict with the type I return!

``````pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {

let mut map = std::collections::HashMap::new();

nums.iter().enumerate().for_each(|(i, k)| {
if let Some(&a) = map.get(&(target - k)) {
return vec![a, i.try_into().unwrap()];
}
map.insert(k, i);
});

// Pass the test
// for (i, k) in nums.iter().enumerate() {
//     if let Some(&a) = map.get(&(target - k)) {
//         return vec![a, i.try_into().unwrap()];
//     }
//     map.insert(k, i.try_into().unwrap());
// }

vec![]
}

#[test]
fn test_two_sum_v1() {
assert_eq!(two_sum(vec![2, 7, 11, 15], 9), vec![0, 1]);
assert_eq!(two_sum(vec![3, 2, 4], 6), vec![1, 2]);
assert_eq!(two_sum(vec![3, 3], 6), vec![0, 1]);
}

``````

This produces the following error:

``````// error[E0308]: mismatched types
//  --> src/lib.rs:7:20
//   |
// 7 |             return vec![a, i.try_into().unwrap()];
//   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Vec<_>`
//   |
//   = note: expected unit type `()`
//                 found struct `Vec<_>`
// note: return type inferred to be `()` here
//  --> src/lib.rs:7:20
//   |
// 7 |             return vec![a, i.try_into().unwrap()];
//   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//   = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
``````

When you use `for_each`, you are passing a closure. The `return` statement is returning from that closure, not the surrounding function. Also, `for_each` expects the closure to return `()` -- that is, it expects it to return nothing.

Edit: and no, there is no way to get a closure to return from an outer function.

Honestly, you should just use `for` rather than `for_each` here. Otherwise, you'll probably have to mess with some combination of `try_fold` and `ControlFlow`, and I can't see it being worth it. I mean, unless you want to figure out how to do it.

4 Likes

Decided to work it out for myself.

``````pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
use std::ops::ControlFlow;

let mut map = std::collections::HashMap::new();

let r = nums.iter()
.enumerate()
.try_for_each(|(i, &k)| {
let i: i32 = i.try_into().unwrap();
if let Some(&a) = map.get(&(target - k)) {
return ControlFlow::Break(vec![a, i]);
}
map.insert(k, i);
ControlFlow::Continue(())
});

match r {
ControlFlow::Break(v) => return v,
ControlFlow::Continue(()) => vec![]
}
}

#[test]
fn test_two_sum_v1() {
assert_eq!(two_sum(vec![2, 7, 11, 15], 9), vec![0, 1]);
assert_eq!(two_sum(vec![3, 2, 4], 6), vec![1, 2]);
assert_eq!(two_sum(vec![3, 3], 6), vec![0, 1]);
}
``````

Like I said, just use `for`.

1 Like

The `ControlFlow``try_fold` group is something I didn't expect, and it's true that using `for` is the simplest way.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.