无法将core :: slice :: Iter解析为core :: iter :: Iterator?

时间:2018-02-21 16:16:22

标签: rust

我正在尝试在Rust中编写一个简单的迭代器:

#[derive(Debug)]
pub struct StackVec<'a, T: 'a> {
    storage: &'a mut [T],
    len: usize,
    _head: usize,
}

impl<'a, T> IntoIterator for StackVec<'a, T> {
    type Item = T;
    type IntoIter = core::slice::Iter<'a, T>;

    fn into_iter(self) -> core::slice::Iter<'a, T> {
        self.storage.iter()
    }
}

但是,在尝试编译时,我收到了这个错误:

error[E0271]: type mismatch resolving `<core::slice::Iter<'_, T> as core::iter::Iterator>::Item == T`
   --> src/lib.rs:135:13
    |
135 | impl<'a, T> IntoIterator for StackVec<'a, T> {
    |             ^^^^^^^^^^^^ expected reference, found type parameter
    |
    = note: expected type `&T`
               found type `T`

error: aborting due to previous error

error: Could not compile `stack-vec`.

有一些令人困惑的错误消息。首先,Rust似乎无法将core::slice::Iter解析为core::iter::Iterator。但是,core::slice::Iter 迭代器,对吗?为什么这些类型不匹配?

其次,我发现期望IntoIterator成为引用而不是类型参数的错误。但是,它的不是一个类型参数。那是什么意思?

我在这里做错了什么?什么是Rust试图告诉我我的代码?

2 个答案:

答案 0 :(得分:6)

  

有一些令人困惑的错误信息。

你是对的,这是一个非常难以解析的信息。

  

似乎Rust无法将core::slice::Iter解析为core::iter::Iterator

你错了:你通过错过一些尖括号错误地解析了这个消息。 (我说很难解析!)让我们看看这条消息,突出了一些关键的括号:

type mismatch resolving `<core::slice::Iter<'_, T> as core::iter::Iterator>::Item == T`
                         (________________________________________________)

问题不是core::slice::Iter<'_, T>解析为core::iter::Iterator,它解决了相等问题,其中整个表达式<core::slice::Iter<'_, T> as core::iter::Iterator>::Item是左侧。整个混乱命名为单一类型:使用as运算符将core::slice::Iter<'_, T>core::iter::Iterator转换为Item,然后选择IntoIterator成员它的。

特征pub trait IntoIterator where <Self::IntoIter as Iterator>::Item == Self::Item 定义如下:

Item

也就是说,要实现特征,您需要满足给定的要求。这是编译器抱怨的要求。您已将T定义为IntoIter,将core::slice::Iter<'_, T>定义为IntoIterator,但将这两个定义置于不满足相等的位置。

换句话说,要实现Item,您需要定义Item类型,它需要与您的基础迭代器的core::slice::Iter<'a, T>类型相同。 Item定义了type Item = &'a T 类型,如下所示:

impl

因此您需要在main()块中使用相同的定义。

Here's a Playground with your definition fixed,以及一个空的function JavaScriptCode() { this['init'] = init; function init() { console.log('init'); } } ,以便进行编译。

答案 1 :(得分:2)

  

首先,似乎Rust无法将core :: slice :: Iter解析为core :: iter :: Iterator。但是,core :: slice :: Iter是一个迭代器,对吗?为什么这些类型不匹配?

你错过了信息的关键部分:

  

类型不匹配解析<std::slice::Iter<'_, T> as std::iter::Iterator>::Item == T

它无法将*解析为Item类型为T的迭代器。

这是因为slice::Iter是引用的迭代器,而不是值。