Array of tuples access in closures - type annotation needed

I am relatively new to Rust, sorry for my ignorance. But the following problem puzzles me:

    let v = [(1, 2)];
    let x = v[0].0; // this works

    let closure = |i| v[i].0; // error[E0282]: type annotation needed (for v[i])
    let y = closure(0);
}

Also, it is not clear to me how/where can I add the type annotation for v[i] in the expression of the closure (other than breaking it up to multiple steps with an extra variable).

The general problem here is that closures can end up having very many possible function signatures, and the type inference algorithm doesn't have a complete answer to correctly guess the right one. Closure typing works best when you pass the closure immediately to another function that's going to call them (like iter.map(|i| i + 1) — anything else is less likely to work automatically.

Also, it is not clear to me how/where can I add the type annotation for v[i] in the expression of the closure

Closures can optionally have parameter types (and return type) specified just like normal functions:

let closure = |i: usize| v[i].0;
2 Likes

Thanks! I was confused by the compiler output (highlighting the entire v[i] part, not just the i). Your answer completely makes sense.

1 Like

General advice: error messages are going to point out the first place the compiler notices there is a fatal problem, not necessarily the best place to fix it. And for type annotations in particular, there are often lots of places you could put them that would suffice, so it's good to take a moment to think about the most relevant or readable one.

The particular reason you got an error where you did is that it's always fatal to have a field access (in this case the field .0 of v[i]) where the type of the structure is unknown, because then the type of the field is also completely unknown.

4 Likes