gpt4 book ai didi

rust - 如何为数据结构实现非消耗可变 std::iter::Iterator

转载 作者:行者123 更新时间:2023-12-03 11:49:02 24 4
gpt4 key购买 nike

我有一个名为 VecCircular 的数据结构,用于非消耗 不可变 std::iter::Iterator 的实现,我遵循了指南 here .这是我的代码:

pub struct VecCircularIterator<'a, T> {
vec_circular: &'a VecCircular<T>,
index: usize,
}

impl<'a, T> std::iter::IntoIterator for &'a VecCircular<T> {
type Item = &'a T;
type IntoIter = VecCircularIterator<'a, T>;

fn into_iter(self) -> Self::IntoIter {
VecCircularIterator {
vec_circular: &self,
index: self.front_index,
}
}
}

impl<'a, T> std::iter::Iterator for VecCircularIterator<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
if self.index == self.vec_circular.rear_index || self.vec_circular.empty() {
return None;
} else {
let item = &self.vec_circular[self.index];
self.index = (self.index + 1) % self.vec_circular.capacity;
return Some(item);
}
}
}

但是当我尝试将该实现更改为可变实现时:
pub struct VecCircularIterator<'a, T> {
vec_circular: &'a mut VecCircular<T>,
index: usize,
}

impl<'a, T> std::iter::IntoIterator for &'a VecCircular<T> {
type Item = &'a T;
type IntoIter = VecCircularIterator<'a, T>;

fn into_iter(self) -> Self::IntoIter {
VecCircularIterator {
vec_circular: &mut self,
index: self.front_index,
}
}
}

impl<'a, T> std::iter::Iterator for VecCircularIterator<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
if self.index == self.vec_circular.rear_index || self.vec_circular.empty() {
return None;
} else {
let item = &self.vec_circular[self.index];
self.index = (self.index + 1) % self.vec_circular.capacity;
return Some(item);
}
}
}

我收到以下错误:
    error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/queue/mod.rs:143:25
|
143 | let item = &self.vec_circular[self.index];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 139:5...
--> src/queue/mod.rs:139:5
|
139 | / fn next(&mut self) -> Option<&'a T> {
140 | | if self.index == self.vec_circular.rear_index || self.vec_circular.empty() {
141 | | return None;
142 | | } else {
... |
146 | | }
147 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/queue/mod.rs:143:25
|
143 | let item = &self.vec_circular[self.index];
| ^^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 137:6...
--> src/queue/mod.rs:137:6
|
137 | impl<'a, T> std::iter::Iterator for VecCircularIterator<'a, T> {
| ^^
note: ...so that the types are compatible
--> src/queue/mod.rs:139:41
|
139 | fn next(&mut self) -> Option<&'a T> {
| _________________________________________^
140 | | if self.index == self.vec_circular.rear_index || self.vec_circular.empty() {
141 | | return None;
142 | | } else {
... |
146 | | }
147 | | }
| |_____^
= note: expected `std::option::Option<&'a T>`
found `std::option::Option<&T>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0495`.
error: could not compile `rudac`.

我对使用rust 生命周期参数有点动摇,我不知道该怎么做。

最佳答案

迭代器不能从自身内部产生借来的值。 next 的 API 声明否则必须绑定(bind) Self::Item终生到self .

您可以产生该值而不是引用,例如,类似这样的东西(但您的代码示例不完整(缺少 VecCircular),因此很难猜测什么是做这件事的好方法):

impl<T> std::iter::Iterator for VecCircularIterator<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
if self.index == self.vec_circular.rear_index || self.vec_circular.empty() {
return None;
} else {
let item = self.vec_circular[self.index];
self.index = (self.index + 1) % self.vec_circular.capacity;
return item;
}
}
}

另请注意,您的 into_iter 存在问题。方法。 into_iter消耗 self 因此,如果您分配对 vec_circular 的引用,它的生命周期将不够长(一旦 into_iter 返回,它就会超出范围)。

顺便提一句。因为看起来你正在自己实现一个队列,你可能也对 VecDeque 感兴趣来自标准库。它还提供 Iter ,它可以产生引用。它通过 not owning the VecDeque itself 做到这一点相反,只是从中借了一片。

关于rust - 如何为数据结构实现非消耗可变 std::iter::Iterator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61349771/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com