The simplest thing to do is probably to build an intermediate vector of vertices to insert and then push them all after you are done iterating over the edges.
Cameron > On Jun 1, 2014, at 12:48 PM, Nicholas Bishop <[email protected]> wrote: > > I'm looking for a little borrow-checker advice. Here's a reasonably > minimal program that demonstrates the problem: > > extern crate collections; > > use collections::HashMap; > > struct G { > verts: HashMap<int, String>, > edges: Vec<(int, int)>, > > next_vert_id: int > } > > impl G { > fn new() -> G { > G{verts: HashMap::new(), edges: Vec::new(), next_vert_id: 0} > } > > fn add_vert(&mut self, s: &str) -> int { > let id = self.next_vert_id; > self.next_vert_id += 1; > self.verts.insert(id, String::from_str(s)); > id > } > > fn add_edge(&mut self, v0: int, v1: int) { > self.edges.push((v0, v1)) > } > } > > fn main() { > let mut g = G::new(); > > { > let v0 = g.add_vert("vert 0"); > let v1 = g.add_vert("vert 1"); > g.add_edge(v0, v1); > } > > for &(v0, v1) in g.edges.iter() { > g.add_vert("edge vert"); > } > } > > This fails to compile: > $ rust-nightly-x86_64-unknown-linux-gnu/bin/rustc -v > rustc 0.11.0-pre-nightly (064dbb9 2014-06-01 00:56:42 -0700) > host: x86_64-unknown-linux-gnu > > $ rust-nightly-x86_64-unknown-linux-gnu/bin/rustc graph.rs > graph.rs:39:9: 39:10 error: cannot borrow `g` as mutable because > `g.edges` is also borrowed as immutable > graph.rs:39 g.add_vert("edge vert"); > ^ > graph.rs:38:22: 38:29 note: previous borrow of `g.edges` occurs here; > the immutable borrow prevents subsequent moves or mutable borrows of > `g.edges` until the borrow ends > graph.rs:38 for &(v0, v1) in g.edges.iter() { > ^~~~~~~ > graph.rs:41:2: 41:2 note: previous borrow ends here > graph.rs:38 for &(v0, v1) in g.edges.iter() { > graph.rs:39 g.add_vert("edge vert"); > graph.rs:40 } > graph.rs:41 } > ^ > error: aborting due to previous error > > My understanding of the error is: G::add_vert is being given a mutable > reference to "g", which means it could do something naughty like clear > g.edges, which would screw up the loop iteration that is happening in > main(). > > That seems like a pretty reasonable thing to prevent, but it's not > clear to me how I should restructure the program to work around the > error. In this minimal example I could copy the code out of > G::add_vert and stick it directly inside the loop, but that's clearly > not the general solution. > > Thanks, > -Nicholas > _______________________________________________ > Rust-dev mailing list > [email protected] > https://mail.mozilla.org/listinfo/rust-dev _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
