为什么索引显式类型的向量会因类型推断错误而失败? [英] Why does indexing an explicitly typed vector fail with a type inference error?

查看:38
本文介绍了为什么索引显式类型的向量会因类型推断错误而失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In the code below, I generate a vector and then use it as content for a closure:

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);
}

为什么虽然显式键入了向量,但代码无法编译并出现类型推断错误?

Why this does code fail to compile with a type inference error although the vector is explicitly typed?

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

推荐答案

Rust 中的 [i] 语法来自于实现 std::ops::Index 特性.

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;
}

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

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]>, 

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

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);

这篇关于为什么索引显式类型的向量会因类型推断错误而失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆