In the code below, I generate a vector and then use it as content for a closure:
fn main() {
let f = {
l
The [i]
syntax in Rust comes from implementing the std::ops::Index trait.
That trait looks like this:
pub trait Index<Idx>
where
Idx: ?Sized,
{
type Output: ?Sized;
fn index(&self, index: Idx) -> &Self::Output;
}
You can implement Index
for a type multiple times, each with a different type for the Idx
parameter. Vec
supports as many different indexing mechanisms as possible by using a blanket implementation of Index
:
impl<T, I> Index<I> for Vec<T>
where
I: SliceIndex<[T]>,
This will work for any type that also has a SliceIndex
implementation, which includes usize
, as you were trying to use, but also range types, like Range<usize>
(e.g. 0..5
) and RangeFrom<usize>
(e.g. 0..
). Inside the closure, the compiler doesn't know which implementation of Index
is going to be used, and each possibility could have a different Output
type, which is why it can't infer a single type there.
You can fix it by annotating the arguments of the closure:
let f = {
let xs: Vec<(usize, usize)> = Vec::new();
//
move |i: usize, j: usize| xs[j].1 - xs[i].0
};
let x = f(1, 2);