我正在尝试在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()
}
}
Run Code Online (Sandbox Code Playgroud)
但是,在尝试编译它时,我收到此错误:
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`.
Run Code Online (Sandbox Code Playgroud)
有一些令人困惑的错误消息.首先,看起来Rust无法解析core::slice::Iteras core::iter::Iterator.但是,core::slice::Iter 是一个迭代器,对吗?为什么这些类型不匹配?
其次,我发现期望IntoIterator成为参考而不是类型参数的错误.但是,它不是一个类型参数.那是什么意思?
我在这做错了什么?什么是Rust试图告诉我我的代码?
有一些令人困惑的错误消息.
你是对的,这是一个非常难以解析的信息.
看起来Rust无法解析
core::slice::Iterascore::iter::Iterator
你错了:错误地解析了消息,错过了一些尖括号.(我说很难解析!)让我们看看这条消息,突出显示了一些关键的括号:
type mismatch resolving `<core::slice::Iter<'_, T> as core::iter::Iterator>::Item == T`
(________________________________________________)
Run Code Online (Sandbox Code Playgroud)
问题并没有解决,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
Run Code Online (Sandbox Code Playgroud)
也就是说,要实现特性,您需要满足给定的要求.这是编译器抱怨的要求.你已经定义Item为as T和IntoIteras core::slice::Iter<'_, T>,但是将这两个定义放在不满足相等性的情况下.
换句话说,要实现IntoIterator,需要定义一个Item类型,它需要与底层迭代器的Item类型相同.core::slice::Iter<'a, T>定义它的Item类型如下:
type Item = &'a T
Run Code Online (Sandbox Code Playgroud)
所以你需要在你的impl块中使用相同的定义.
这是一个游戏,你的定义是固定的,一个空的main()所以它将编译.