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

Nicholas Bishop nicholasbishop at gmail.com
Sun Jun 1 14:15:43 PDT 2014


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 <zwarich at mozilla.com> 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
> <christophe.pedretti at gmail.com> wrote:
>
> 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
>
>
> _______________________________________________
> 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
>


More information about the Rust-dev mailing list