1

I'm implementing a basic data structure. I think I understand why the following code doesn't work: I can't mutably borrow and try to access (read) the value at the same time. However, I am stuck on how to implement add_ege.

The whole idea is to have Graph hold a list of Nodes in the heap. The Node itself keeps track of adjacent nodes (edges). I don't want Node to hold copies of Node, I want it to have references to any of the Nodes held in Graph.

struct Node<'a> {
    value: String,
    adj_nodes: Vec<&'a Node<'a>>, // refer to Graph.nodes
}

pub struct Graph<'a> {
    nodes: Vec<Box<Node<'a>>>,
}

fn mk_node<'a>(value: String) -> Node<'a> {
    Node {
        value,
        adj_nodes: vec![],
    }
}

pub fn mk_graph<'a>() -> Graph<'a> {
    let nodes = vec![];
    Graph { nodes }
}

impl<'a> Graph<'a> {
    fn add_node(&mut self, val: String) {
        let node = Box::new(mk_node(val));
        self.nodes.push(node);
    }

    fn add_edge(&mut self, from_node: &'a mut Node<'a>, to_node: &'a mut Node<'a>) {
        from_node.adj_nodes.push(to_node);
        // won't work because I already have from_node as mutable borrow
        to_node.adj_nodes.push(from_node);
    }
}

Is there a way to do this?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Shulhi Sapli
  • 2,286
  • 3
  • 21
  • 31
  • 1
    Rust is very keen about *DAG* relationships between objects, whereas graphs can naturally involve circles. Have you tried looking for "rust graph site:stackoverflow.com" on Google? The first answer is https://stackoverflow.com/questions/34747464/implement-graph-like-datastructure-in-rust which seems very relevant. – Matthieu M. Dec 03 '17 at 12:43
  • I did, I changed how I implement my graph structure so I don't actually have the issue. I guess that is not doable. The goal is not to build a complete graph library, it is more on learning Rust. – Shulhi Sapli Dec 03 '17 at 13:04
  • 1
    Actually, you still have the issue: a `Node` referencing any other `Node` means that you have cycles, and therefore that you don't have a *DAG*. How can I put it... ownership and references somehow mix up in Rust, you can't consider one without the other because a reference has an associated lifetime tying it to the owner of the object it references. It's not sufficient, therefore, to have a DAG of owners, you must have a DAG of owners & references. Or cheat. The `TypedArena` I mentioned is such a way to cheat: within the lifetime of the arena, cycles are allowed. – Matthieu M. Dec 03 '17 at 13:22
  • I'm not sure if I get it, probably just some of it. I found few links regarding the graphs and arena allocation and will give it a read. I appreciate your help, thanks! – Shulhi Sapli Dec 03 '17 at 13:35
  • See also: https://stackoverflow.com/q/36565833/155423. – Shepmaster Dec 03 '17 at 15:02

0 Answers0