无法从闭包 return 值中移出借用的内容
Cannot move out of borrowed content from closure return value
我在处理一个中型项目时发现了这个问题。以下代码段是问题的最小摘要。
在下面的代码中,我尝试将枚举变体列表映射到一组不同的枚举变体中。我使用闭包,因此我可以捕获对 my_list
的可变引用,它是 source 枚举变体的列表。然后将闭包保存在 MyType
实例中,以便稍后调用它并在另一个方法中使用结果。
为了保持闭包,我在 Box
中使用了 FnMut
特征。我还将它包装在 Option
中,这样我就可以在创建实例后设置闭包。
我是根据这里问的问题得出这个结论的:structs with boxed vs. unboxed closures
use std::collections::HashSet;
enum Numbers {
One,
Two,
Three,
}
#[derive(Eq, PartialEq, Hash)]
enum Romans {
I,
II,
III,
}
struct MyType<'a> {
func: Option<Box<dyn FnMut() -> HashSet<Romans> + 'a>>,
}
impl<'a> MyType<'a> {
pub fn set_func<F>(&mut self, a_func: F)
where F: FnMut() -> HashSet<Romans> + 'a {
self.func = Some(Box::new(a_func));
}
pub fn run(&mut self) {
let result = (self.func.unwrap())();
if result.contains(&Romans::I) {
println!("Roman one!");
}
}
}
fn main() {
let my_list = vec![Numbers::One, Numbers::Three];
let mut my_type = MyType {
func: None,
};
my_type.set_func(|| -> HashSet<Romans> {
HashSet::from(my_list
.iter()
.map(|item| {
match item {
Numbers::One => Romans::I,
Numbers::Two => Romans::II,
Numbers::Three => Romans::III,
}
})
.collect()
)
});
my_type.run();
}
当我尝试编译时,出现以下错误:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:27:23
|
27 | let result = (self.func.unwrap())();
| ^^^^^^^^^ cannot move out of borrowed content
error: aborting due to previous error
我不太明白搬出的是什么。是隐藏的self
吗?结果HashSet
?或者集合中的值?
我做错了什么?
您遇到的麻烦是在 Option
上调用 unwrap
会消耗它——它需要 self
作为参数。在 run()
中,您的 MyType
只有一个 &mut self
对自身的引用,因此它无法取得其字段的所有权。
解决方案是采用对存储函数的可变引用:
pub fn run(&mut self) {
if let Some(func) = &mut self.func {
let result = func();
if result.contains(&Romans::I) {
println!("Roman one!");
}
}
}
我在处理一个中型项目时发现了这个问题。以下代码段是问题的最小摘要。
在下面的代码中,我尝试将枚举变体列表映射到一组不同的枚举变体中。我使用闭包,因此我可以捕获对 my_list
的可变引用,它是 source 枚举变体的列表。然后将闭包保存在 MyType
实例中,以便稍后调用它并在另一个方法中使用结果。
为了保持闭包,我在 Box
中使用了 FnMut
特征。我还将它包装在 Option
中,这样我就可以在创建实例后设置闭包。
我是根据这里问的问题得出这个结论的:structs with boxed vs. unboxed closures
use std::collections::HashSet;
enum Numbers {
One,
Two,
Three,
}
#[derive(Eq, PartialEq, Hash)]
enum Romans {
I,
II,
III,
}
struct MyType<'a> {
func: Option<Box<dyn FnMut() -> HashSet<Romans> + 'a>>,
}
impl<'a> MyType<'a> {
pub fn set_func<F>(&mut self, a_func: F)
where F: FnMut() -> HashSet<Romans> + 'a {
self.func = Some(Box::new(a_func));
}
pub fn run(&mut self) {
let result = (self.func.unwrap())();
if result.contains(&Romans::I) {
println!("Roman one!");
}
}
}
fn main() {
let my_list = vec![Numbers::One, Numbers::Three];
let mut my_type = MyType {
func: None,
};
my_type.set_func(|| -> HashSet<Romans> {
HashSet::from(my_list
.iter()
.map(|item| {
match item {
Numbers::One => Romans::I,
Numbers::Two => Romans::II,
Numbers::Three => Romans::III,
}
})
.collect()
)
});
my_type.run();
}
当我尝试编译时,出现以下错误:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:27:23
|
27 | let result = (self.func.unwrap())();
| ^^^^^^^^^ cannot move out of borrowed content
error: aborting due to previous error
我不太明白搬出的是什么。是隐藏的self
吗?结果HashSet
?或者集合中的值?
我做错了什么?
您遇到的麻烦是在 Option
上调用 unwrap
会消耗它——它需要 self
作为参数。在 run()
中,您的 MyType
只有一个 &mut self
对自身的引用,因此它无法取得其字段的所有权。
解决方案是采用对存储函数的可变引用:
pub fn run(&mut self) {
if let Some(func) = &mut self.func {
let result = func();
if result.contains(&Romans::I) {
println!("Roman one!");
}
}
}