rust 可变迭代器[重复]

ttvkxqim  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(112)
    • 此问题在此处已有答案**:

How can I create my own data structure with an iterator that returns mutable references?(1个答案)
How to implement Iterator yielding mutable references [duplicate](2个答案)
3天前关闭。
我试图在一个向量上编写一个可变迭代器,但是我无法理解编译器想要告诉我什么。

struct IterMut<'a> {
    vec: &'a mut Vec<u32>,
    index: usize,
}

impl<'a> Iterator for IterMut<'a> {
    type Item = &'a mut u32;

    fn next(&mut self) -> Option<Self::Item> {
        let item = if self.index < self.vec.len() {
            Some(&mut self.vec[self.index])
        } else {
            None
        };

        self.index += 1;

        item
    }
}

编译器错误为:

error: lifetime may not live long enough
  --> src/main.rs:60:9
   |
48 | impl<'a> Iterator for IterMut<'a> {
   |      -- lifetime `'a` defined here
...
51 |     fn next(&mut self) -> Option<Self::Item> {
   |             - let's call the lifetime of this reference `'1`
...
60 |         item
   |         ^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`

不可变的版本编译并工作。

struct Iter<'a> {
    vec: &'a Vec<u32>,
    index: usize,
}

impl<'a> Iterator for Iter<'a> {
    type Item = &'a u32;

    fn next(&mut self) -> Option<Self::Item> {
        let item = if self.index < self.vec.len() {
            Some(&self.vec[self.index])
        } else {
            None
        };

        self.index += 1;

        item
    }
}

Here is a playground link with the code to try out.

carvr3hs

carvr3hs1#

问题是IterMut保留了已经传递的元素。
它只能通过重新借用该项目来实现这一点,但这意味着该项目不再是从原始Vec借用的,而是从IterMut借用的,因此它的寿命不够长。(重新借用的寿命仅与IterMut一样长,而不是与原始Vec一样长。
在夜间或take_first_mut稳定后,您可以执行以下操作:

#![feature(slice_take)]
struct IterMut<'a> {
    vec: &'a mut [u32],
}

impl<'a> Iterator for IterMut<'a> {
    type Item = &'a mut u32;

    fn next(&mut self) -> Option<Self::Item> {
        self.vec.take_first_mut()
    }
}

注意我从&mut Vec<u32>切换到了切片,因为您必须能够“释放”项目,这对于Vec来说并不容易
正如@ChayimFriedman在stable上指出的那样,您可以同时使用mem::take

struct IterMut<'a> {
    vec: &'a mut [u32],
}

impl<'a> Iterator for IterMut<'a> {
    type Item = &'a mut u32;

    fn next(&mut self) -> Option<Self::Item> {
        let (first, rem) = std::mem::take(&mut self.vec).split_first_mut()?;
        self.vec = rem;
        Some(first)
    }
}

相关问题