I haven't tried this at all, but could iterating over the range [ 0, g.edges.len() ) work?
On Sun, Jun 1, 2014 at 2:26 PM, Cameron Zwarich <[email protected]> wrote: > It’s difficult to do something better without somewhat breaking the > encapsulation of your graph type, but you could split G into edge and > vertex data structures and have the functions that add vertices / edges > operate on part of . Then given an &mut G, you could reborrow the vertex > data and the edge data with &mut pointers separately. > > This is tricky because not all implementations of a graph interface allow > separate modification of vertex and edge data, so to exploit this you have > to expose your representation somewhat. > > Cameron > > On Jun 1, 2014, at 2:15 PM, Nicholas Bishop <[email protected]> > wrote: > > > Building an intermediate would work, but it implies extra overhead. If > > this was a large graph instead of just one edge then it could be > > expensive to copy from the intermediate back into the original object. > > Are there any alternatives to consider? > > > > On Sun, Jun 1, 2014 at 4:48 PM, Cameron Zwarich <[email protected]> > wrote: > >> `mut_iter` only gives you mutable references to the elements of the > >> container; it doesn’t allow you to reborrow the container itself mutably > >> inside of the loop. > >> > >> Cameron > >> > >> On Jun 1, 2014, at 1:39 PM, Christophe Pedretti > >> <[email protected]> wrote: > >> > >> and using mut_iter() instead of iter() is not enough ? > >> > >> > >> 2014-06-01 22:03 GMT+02:00 Cameron Zwarich <[email protected]>: > >>> > >>> 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 > >> > >> > >> _______________________________________________ > >> 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 > >> > > _______________________________________________ > 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
