为什么索引显式类型的向量失败并出现类型推断错误?

时间:2019-06-15 14:39:17

标签: types rust

在下面的code中,我生成一个向量,然后将其用作闭包的内容:

fn main() {
    let f = {
        let xs: Vec<(usize, usize)> = Vec::new();
        // populate xs
        move |i, j| xs[j].1 - xs[i].0
    };
    let x = f(1usize, 2usize);
}

为什么虽然显式键入了向量,但是为什么代码无法通过类型推断错误进行编译?

error[E0282]: type annotations needed
 --> src/main.rs:5:21
  |
5 |         move |i, j| xs[j].1 - xs[i].0
  |                     ^^^^^ cannot infer type
  |
  = note: type must be known at this point

1 个答案:

答案 0 :(得分:5)

Rust中的[i]语法来自实现std::ops::Index trait

该特征看起来像这样:

pub trait Index<Idx> 
where
    Idx: ?Sized, 
{
    type Output: ?Sized;
    fn index(&self, index: Idx) -> &Self::Output;
}

您可以为一个类型多次实现Index,每个Idx参数都具有不同的类型。 Vec通过使用Index的统一实现来支持尽可能多的不同索引机制:

impl<T, I> Index<I> for Vec<T>
where
    I: SliceIndex<[T]>, 

这将适用于也有SliceIndex实现的任何类型,包括您尝试使用的usize,以及范围类型,例如Range<usize>(例如{{ 1}}和0..5(例如RangeFrom<usize>)。在闭包内部,编译器不知道将使用0..哪种实现,每种可能性都可能具有不同的Index类型,这就是为什么它可以在那里不能推断出单一类型。

您可以通过注释闭包的参数来修复它:

Output