> I haven't tried this at all, but could iterating over the range [ 0, > g.edges.len() ) work?
An interesting suggestion, but doesn't extend easily to other types of containers like HashMaps. > 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. I'll give that a try. It should be enough to get me past immediate problems at least. -Nicholas >> >> 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 > _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
