闭包需要独特的访问 [英] closure requires unique access

查看:127
本文介绍了闭包需要独特的访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过在以下代码中使用闭包重复自己:

I'm trying to avoid repeating myself by using a 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);
}

这不行。它给我这个错误:

That doesn't work. It 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'm not actually saving myself too many keystrokes. I can type everything out by hand 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 (so I think), but:


  1. 在这里使用闭包是否有什么问题,或者我写错了?


  2. 这可能是一个暗淡的问题,但为什么不是借用刚刚结束后立即结束?最后一次 convert 被调用?对我来说看起来很奇怪,特别是当我将它与底部版本进行比较时,最终会执行相同的步骤减去闭包。

  1. Is there something wrong with using a closure here in principal or did I just write this wrong?
  2. Is there a more idiomatic way to write this, or at least, how do I satisfy the borrow checker?
  3. This might be a dim question, but why doesn't the borrow just end immediately after the last time convert is called? It seems strange to me especially when I compare it to the bottom version, which ultimately does the same steps minus the closure.


推荐答案

您应该能够像这样修改它(您称为满足借入检查器):

You should be able to fix it like this (something you called "satisfy the borrow checker"):

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 引用,但不一定与可变性有关。闭包环境捕获在其创建时发生,所以这个捕获的生命周期延续到函数的结尾,因此你会得到错误。

As far as I know, this is something inexpressible in current Rust directly (i.e. without closures). Closures take their environment through &only reference (currently it is only available to compiler), which forbids taking other references until it goes out of scope. It is like &mut reference but not necessarily tied to mutability. Closure environment capture happens upon its creation, so lifetime of this capture extends to the end of the function, hence you're getting the error.

为什么闭包应该采取他们的环境通过独特的参考,我不知道,虽然。

Why closures should take their environment by unique reference I don't know, though.

这篇关于闭包需要独特的访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆