【问题标题】:Cannot resolve core::slice::Iter as core::iter::Iterator?无法将 core::slice::Iter 解析为 core::iter::Iterator?
【发布时间】:2018-02-21 16:16:22
【问题描述】:

我正在尝试用 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 试图告诉我什么?

【问题讨论】:

    标签: rust


    【解决方案1】:

    此错误消息有几处令人困惑。

    你说得对,这是一个很难解析的消息。

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

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

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

    问题不是将core::slice::Iter&lt;'_, T&gt; 解析为core::iter::Iterator,而是解决了等式,其中整个表达式&lt;core::slice::Iter&lt;'_, T&gt; as core::iter::Iterator&gt;::Item 是左侧。整个混乱命名了一个类型:这是您通过使用as 运算符将core::slice::Iter&lt;'_, T&gt; 向上转换为core::iter::Iterator,然后获取它的Item 成员得到的类型。

    特征IntoIterator定义如下:

    pub trait IntoIterator where
        <Self::IntoIter as Iterator>::Item == Self::Item
    

    也就是说,要实现 trait,你需要满足给定的要求。这是编译器抱怨的要求。您已将Item 定义为T,并将IntoIter 定义为core::slice::Iter&lt;'_, T&gt;,但是将这两个定义放入其中并不能满足相等性。

    换句话说,要实现IntoIterator,您需要定义一个Item 类型,它需要与您的底层迭代器的Item 类型相同。 core::slice::Iter&lt;'a, T&gt; 定义其 Item 类型如下:

    type Item = &'a T
    

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

    Here's a Playground with your definition fixed 和一个空的main(),这样它就会编译。

    【讨论】:

    • 啊!谢谢您的帮助!现在这完全有道理。
    【解决方案2】:

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

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

    类型不匹配解决&lt;std::slice::Iter&lt;'_, T&gt; as std::iter::Iterator&gt;::Item == T

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

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

    【讨论】:

    • 所以,我尝试将我的实现更改为:self.storage.into_iter(),但我仍然看到相同的错误消息。那应该返回值的迭代器,而不是引用,对吗?
    • @bioball 你的self.storage 是对数据的可变引用,是其他地方拥有的一些数据的一部分。在 &amp;mut [T] 上调用 into_iter 不会为您提供拥有值的迭代器,因为您一开始并不拥有数据。
    猜你喜欢
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 2023-01-25
    • 1970-01-01
    相关资源
    最近更新 更多