我试图通过在以下代码中使用闭包来避免重复自己:
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);
}
这不起作用。它给了我这个错误:
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
在这种情况下,我实际上并没有为自己节省太多的击键次数。我可以手动输入所有内容,它可以正常工作:
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);
}
我理解错误(所以我认为),但是:
convert
后立即结束?这对我来说似乎很奇怪,特别是当我将它与底部版本进行比较时,它最终会采用相同的步骤减去封闭。答案 0 :(得分:2)
你应该能够像这样修理它(你称之为“满足借用检查器”):
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
引用,但不一定与可变性相关。闭包环境捕获在创建时发生,因此捕获的生命周期延伸到函数的末尾,因此您将收到错误。
为什么闭包应该通过我不知道的唯一引用来占用他们的环境。