-1

I have implemented a custom iterator for a graph traversal. The iterator contains state variables which I plan to access inside the body of the loop:

#[derive(Clone, Debug)]
pub struct NodeIterator<'a, T: 'a + Data> {
    graph: &'a DAG<T>,

    /// true if we should fetch the nodes recursively (default = true)
    pub recursive: bool,

    /// true if we explore depth first, and after that go for neighour nodes (default=false)
    pub depth_first: bool,

    /// maximum depth to iterate on lower levels
    /// recursive = true : we use recursion to iterate down the hierarchy
    /// recursive =false : we only iterate either through children or parents
    ///                                  (depending on follow_direction field)
    pub max_depth: NodeID,

    /// follow_direction = true : we iterate using 'parents' vec
    /// follow_direction =false : we iterate using 'children' vec
    pub follow_direction: bool,

    /// current node, that was already provided by the iterator
    pub cur_node_id: Option<NodeID>,

    /// index to the current children or parent (while iterating corresponding collection)
    pub cur_index: Option<NodeID>,

    /// current Edge being iterated
    pub cur_edge: Option<Edge>,

    /// current depth (starts from 0)
    cur_depth: u32,
}

impl<'a, T> NodeIterator<'a, T>
where
    T: 'a + Data,
{
    pub fn get_cur_depth(&self) -> u32 {
        self.cur_depth
    }
}

When I use it in a for loop, it takes ownership of the object:

let it = graph.iter();
for node_entry in it {
    println!(
        "node_id: {}, depth: {},",
        node_entry.node_id,
        it.get_cur_depth()
    );
}

If I try to use it inside the code block, I get this error:

     ^^ value used here after move

The error occurs when I am trying to acces to it.get_cur_depth() function. How would you get around this error to access internal state of the iterator through methods?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Nulik
  • 6,748
  • 10
  • 60
  • 129

1 Answers1

2

When I use it in a for loop, it takes ownership of the object:

Then don't use a for loop:

fn main() {
    let s = "a b c";
    let mut it = s.chars();

    while let Some(_) = it.next() {
        println!("remaining: {},", it.as_str());
    }
}

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 1
    Moreover, to understand what `for` is actually doing under the hood consult the relevant chapters of [The Rust Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops) – Peter Varo Jun 04 '19 at 23:22