Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Implement the IntoIter and Iterator trait for VecData<T>(Rc<RefCell<Rc<Vec<T>>>>)

I have a relatively complex data structure (for reasons I don’t want to go into here).
It is defined as

pub struct VecData<T>(Rc<RefCell<Rc<Vec<T>>>>);

What I am looking for is a way to implement the IntoIter and Iterator traits for this struct. To be precise, I want to be able to iterate over the elements of type &T without cloning the inner Vec<T>.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You cannot do that, but you can come close, by yielding Ref<T> instead:

use std::cell::{Ref, RefCell};
use std::rc::Rc;

pub struct VecData<T>(Rc<RefCell<Rc<Vec<T>>>>);

impl<T> VecData<T> {
    pub fn iter(&self) -> Iter<'_, T> {
        Iter {
            data: self.0.borrow(),
            index: 0,
        }
    }
}

pub struct Iter<'a, T> {
    data: Ref<'a, Rc<Vec<T>>>,
    index: usize,
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = Ref<'a, T>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.index >= self.data.len() {
            return None;
        }

        let item = Ref::map(Ref::clone(&self.data), |data| &data[self.index]);
        self.index += 1;
        Some(item)
    }
}

The reasoning you cannot do that is as follows: imagine you could do that, then you could create the iterator, extract the first item out of it then drop the iterator. Now you have a &T pointing to inside the Rc<Vec>, and no bookkeeping to inform the RefCell it is borrowed. Now you replace the inner Rc by borrow_mut()ing the RefCell. You got a dangling reference! Surely this has to be disallowed.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading