2

I want to find some node in the tree and I need a pointer to the container of nodes: &mut Vec<Node>

struct Node {
    c: Vec<Node>,
    v: i32,
}

impl Node {
    pub fn new(u: i32, n: Node) -> Node {
        let mut no = Node {
            c: Vec::new(),
            v: u,
        };

        no.c.push(n);

        no
    }
}

fn main() {
    let mut a = Node::new(1,
        Node::new(2,
        Node::new(3,
        Node::new(4,
        Node::new(5,
        Node {
            c: Vec::new(),
            v: 6,
        })))));

    let mut p: &mut Vec<Node> = &mut a.c;

    while p.len() > 0 {
        p = &mut p[0].c;
    }

    p.push(Node {
        c: Vec::new(),
        v: 7,
    });
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
J. Jerk
  • 23
  • 3

1 Answers1

4

You need a temporary variable to calm down the borrow checker:

while p.len() > 0 {
    let t = p;
    p = &mut t[0].c;
}

Or:

while p.len() > 0 {
    p = &mut {p}[0].c;
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
aSpex
  • 4,790
  • 14
  • 25
  • Thanks. I can not understand, why lifetime in rust ends with brackets { }, I think, lifetime should end then this variable uses last time. – J. Jerk Jun 19 '16 at 10:00
  • @J.Jerk lifetime is a time limits of a variable which begins from allocation and ends with deallocation. Deallocation process takes place when the variable goes out of its scope. [Read more](https://doc.rust-lang.org/book/lifetimes.html#thinking-in-scopes) – VP. Jun 19 '16 at 10:16
  • @J.Jerk This is not lifetime issue. Borrow checker thinks that `p` is mutably borrowed by itself here: `p=&mut p[0].c`. After that `p` is locked, you can't do anything anymore with it. Replacing `p` with temporary variable allows to avoid self-locking. – aSpex Jun 19 '16 at 10:49
  • It's when I see such work-arounds that I realize the compiler could benefit from some tweaking on lifetimes :D – Matthieu M. Jun 20 '16 at 08:41