[rust-dev] Calling a method while iterating over a field of the object

Christophe Pedretti christophe.pedretti at gmail.com
Sun Jun 1 13:39:55 PDT 2014


and using mut_iter() instead of iter() is not enough ?


2014-06-01 22:03 GMT+02:00 Cameron Zwarich <zwarich at mozilla.com>:

> 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 <nicholasbishop at gmail.com>
> 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
> > Rust-dev at mozilla.org
> > https://mail.mozilla.org/listinfo/rust-dev
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140601/1e0c1f12/attachment.html>


More information about the Rust-dev mailing list