【发布时间】:2015-03-09 03:05:04
【问题描述】:
FnMut 闭包不能被克隆,原因很明显,但 Fn 闭包具有不可变范围;有什么方法可以创建 Fn 闭包的“副本”吗?
尝试克隆它会导致:
error[E0599]: no method named `clone` found for type `std::boxed::Box<std::ops::Fn(i8, i8) -> i8 + std::marker::Send + 'static>` in the current scope
--> src/main.rs:22:25
|
22 | fp: self.fp.clone(),
| ^^^^^
|
= note: self.fp is a function, perhaps you wish to call it
= note: the method `clone` exists but the following trait bounds were not satisfied:
`std::boxed::Box<std::ops::Fn(i8, i8) -> i8 + std::marker::Send> : std::clone::Clone`
以某种方式将原始指针传递给Fn 是否安全,例如:
let func_pnt = &mut Box<Fn<...> + Send> as *mut Box<Fn<...>>
从技术上讲,上述方法可行,但看起来很奇怪。
这是我正在尝试做的一个示例:
use std::thread;
struct WithCall {
fp: Box<Fn(i8, i8) -> i8 + Send>,
}
impl WithCall {
pub fn new(fp: Box<Fn(i8, i8) -> i8 + Send>) -> WithCall {
WithCall { fp: fp }
}
pub fn run(&self, a: i8, b: i8) -> i8 {
(self.fp)(a, b)
}
}
impl Clone for WithCall {
fn clone(&self) -> WithCall {
WithCall {
fp: self.fp.clone(),
}
}
}
fn main() {
let adder = WithCall::new(Box::new(|a, b| a + b));
println!("{}", adder.run(1, 2));
let add_a = adder.clone();
let add_b = adder.clone();
let a = thread::spawn(move || {
println!("In remote thread: {}", add_a.run(10, 10));
});
let b = thread::spawn(move || {
println!("In remote thread: {}", add_b.run(10, 10));
});
a.join().expect("Thread A panicked");
b.join().expect("Thread B panicked");
}
我有一个带有盒装闭包的结构,我需要将该结构传递给多个线程。我不能,但我也不能克隆它,因为你不能克隆Box<Fn<>>,也不能克隆&Fn<...>。
【问题讨论】:
-
你想用克隆的闭包做什么?
-
你的完整代码是什么?
-
@shepmaster 我特别想克隆一个没有可变状态的闭包,以便同时将其移动到多个任务中。请参阅我附上的示例。
-
"你不能克隆 &Fn<...>"。你can,特别是
?Sized,意味着它适用于特征对象。 -
@dbaupp Box::new(*(&(*self.fp)).clone()) -> 错误:特征
core::marker::Sized没有为core::ops::Fn(i8, i8) -> i8 + Send类型实现跨度>