我正在尝试在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试图告诉我我的代码?
答案 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
是引用的迭代器,而不是值。