capitrane
capitrane

Reputation: 487

How do I return a reference to a part of a recursive data structure?

I'm trying to define a recursive data structure in Rust, but there are some pieces missing in my understanding of Rust and memory - the only thing that I manage to do is pick a fight with the borrow checker.

I have the following stub of a quad tree and want to project one of the quadrants as follows.

use CC::{Node, Leaf};

enum CC {
    Node(i32, bool, i32, Rc<CC>, Rc<CC>, Rc<CC>, Rc<CC>),
    Leaf(bool),
}

impl CC {
    fn nw(&self) -> CC {
        match *self {
            Node(_, _, _, ref nw, _, _, _) => *nw.clone(),
            _ => panic!()
        }
    }
}

But all I end up with is

src/hashlife.rs:34:47: 34:58 error: cannot move out of borrowed content
src/hashlife.rs:34             Node(_, _, _, ref nw, _, _, _) => *nw.clone(),
                                                                 ^~~~~~~~~~~

Upvotes: 0

Views: 236

Answers (1)

Vladimir Matveev
Vladimir Matveev

Reputation: 127961

You have two options here.

First, you can return a reference to the subtree:

fn nw(&self) -> &CC {
    match *self {
        Node(_, _, _, ref nw, _, _, _) => &**nw,
        _ => panic!()
    }
}

Second, you can return a reference-counted pointer:

fn nw(&self) -> Rc<CC> {
    match *self {
        Node(_, _, _, ref nw, _, _, _) => nw.clone()
        _ => panic!()
    }
}

You can't return just CC, however, unless you are willing to clone the value itself. The reason is that this would mean moving out of Rc, leaving it in some undefined state, which is rightly prohibited.

Upvotes: 3

Related Questions