Closing requires unique access

I try to avoid repeating myself using closure in the following code:

fn add_raw(&mut self, pair: RawLinkPair) {
    let convert = |raw: &RawLink| {
        Link{
            id:         self.get_or_create(raw.name).id,
            flow:       raw.flow,
        }
    };

    println!("Hive received pair: {}", pair);
    let parent = convert(&pair.parent);
    let child = convert(&pair.child);
    self.link_concepts(parent, child);
}

This does not work. This gives me this error:

hive.rs:64:9: 64:13 error: cannot borrow `*self` as mutable because previous closure requires unique access
hive.rs:64         self.link_concepts(parent, child);
                   ^~~~
hive.rs:55:23: 60:10 note: previous borrow of `self` occurs here due to use in closure; the unique capture prevents subsequent moves or borrows of `self` until the borrow ends
hive.rs:55         let convert = |raw: RawLink| {
hive.rs:56             Link{
hive.rs:57                 id:         self.get_or_create(raw.name).id,
hive.rs:58                 flow:       raw.flow,
hive.rs:59             }
hive.rs:60         };
hive.rs:65:6: 65:6 note: previous borrow ends here
hive.rs:54     fn add_raw(&mut self, pair: RawLinkPair) {
...
hive.rs:65     }
               ^
error: aborting due to previous error

In this case, I don’t actually save too many keystrokes. I can print everything manually and it works fine:

fn add_raw(&mut self, pair: RawLinkPair) {
    let parent = Link {
        id:     self.get_or_create(pair.parent.name).id,
        flow:   pair.parent.flow,
    };

    let child = Link {
        id:     self.get_or_create(pair.child.name).id,
        flow:   pair.child.flow,
    };

    self.link_concepts(parent, child);
}

I understand the error (as I think), but:

  • Is there something wrong with using closure here in principle or did I just write it wrong?
  • Is there a more idiomatic way to write this, or at least how can I do a check check?
  • This may be a dull question, but why does borrowing just end right after the last call convert? It seems strange to me, especially when I compare it with the lower version, which ultimately takes the same steps minus closing.
+1
1

(-, " " ):

fn add_raw(&mut self, pair: RawLinkPair) {
    let (parent, child) = {
        let convert = |raw: RawLink| {
            Link{
                id:         self.get_or_create(raw.name).id,
                flow:       raw.flow,
            }
        };

        (convert(pair.parent.clone()), convert(pair.child.clone()))
    };
    self.link_concepts(parent, child);
}

, , Rust (.. ) - . &only ( ), , . &mut, . Closure , , .

, .

+2

Source: https://habr.com/ru/post/1546799/


All Articles