How to implement a container with mutable iterator support?

I want to create a toy container class with support for mutable iterators, but I am having problems sorting the iterator's lifetime and its reference to the container.

I tried to create a minimal non-compiling example:

struct Payload {
    value: i32,
}

struct Container {
    val: Payload,
}

struct IterMut<'a> {
    cont: &'a mut Container,
    cnt: i32,
}

impl<'a> Container {
    fn new() -> Container {
        Container { val: Payload { value: 42 } }
    }
    fn iter_mut(&'a mut self) -> IterMut<'a> {
        IterMut {
            cont: self,
            cnt: 10,
        }
    }
}

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

    fn next<'b>(&'b mut self) -> Option<Self::Item> {
        self.cnt -= 1;

        if self.cnt < 0 {
            return None;
        } else {
            Some(&mut self.cont.val)
        }
    }
}

fn main() {
    let mut cont = Container::new();

    let mut it = cont.iter_mut();
    it.next();
}

The above is for implementing a real dumb container that returns the same element 10 times when repeated using iter_mut().

I can’t figure out how to implement it Iterator::next.

I managed to write a regular function that implements the same semantics as I do for next:

fn manual_next<'a, 'b>(i: &'a mut IterMut<'b>) -> Option<&'a mut Payload> {
    i.cnt -= 1;

    if i.cnt < 0 {
        return None;
    } else {
        Some(&mut i.cont.val)
    }
}

, Iterator::next, Iterator for-loops, .

+4
1

, , / Rust. , !: -)

, main:

fn main() {
    let mut cont = Container::new();

    let mut it = cont.iter_mut();
    let alias_1 = it.next();
    let alias_2 = it.next();
    // alias_1 and alias_2 both would have mutable references to cont.val!
}

iter_mut (, /) , .

- , , RefCell Cell.

manual_next , Iterator::next, ( , ). , , IterMut , :

let mut cont = Container::new();

let mut it = cont.iter_mut();
let x = manual_next(&mut it);
manual_next(&mut it);  // Error: `it` is still borrowed mutably

, Iterator::next , , collect ing, .

+5

Source: https://habr.com/ru/post/1669792/


All Articles