如何为带盒装闭包的结构派生克隆?
How to derive Clone for structures with boxed closure?
我有以下结构:
struct MyStruct {
foo: Box<dyn Fn(usize) -> usize>
}
我想为 MyStruct
导出 Clone
。但是,编译器出现错误:
the trait bound `dyn std::ops::Fn(usize) -> usize: std::clone::Clone` is not satisfied
目前(rustc 1.46.0),dyn
不支持添加非自动特征,如 Box<dyn Fn(usize) -> usize + Clone>
。
A closure is Clone
or Copy
if it does not capture any values by unique immutable or mutable reference, and if all values it captures by copy or move are Clone
or Copy
, respectively.
所以我觉得这个推导在理论上是有道理的,但是我暂时不知道能不能做到。
我不介意为 MyStruct
手动实现 Clone
,但我也不知道该怎么做。
我不想做类似
的事情
#[derive(Clone)]
struct MyStruct<F: Fn(usize) -> usize> {
foo: F
}
因为这个结构被用作实现另一个特征结构的关联类型,而且那个结构和特征都没有泛型,我不想搞砸 PhantomData
.
扩展上面的@mcarton 评论,但使用 dyn-clone
板条箱来克服 Clone
不是对象安全的问题,代码非常简单。
use dyn_clone::DynClone;
trait FnClone: DynClone {
fn call(&self, x: usize) -> usize;
}
impl<F> FnClone for F
where F: Fn(usize) -> usize + Clone
{
fn call(&self, x: usize) -> usize {
self(x)
}
}
struct MyStruct {
foo: Box<dyn FnClone>
}
impl Clone for MyStruct {
fn clone(&self) -> MyStruct {
MyStruct {
foo: dyn_clone::clone_box(&*self.foo),
}
}
}
fn main() {
let a = MyStruct{
foo: Box::new(|x| x + 1)
};
let b = a.clone();
println!("{} {}", a.foo.call(1), b.foo.call(2));
}
这个 crate 还提供了一个宏 clone_trait_object!
来使 Clone
可以派生为 Box<dyn FnClone>
,但你似乎不希望这样。
我有以下结构:
struct MyStruct {
foo: Box<dyn Fn(usize) -> usize>
}
我想为 MyStruct
导出 Clone
。但是,编译器出现错误:
the trait bound `dyn std::ops::Fn(usize) -> usize: std::clone::Clone` is not satisfied
目前(rustc 1.46.0),dyn
不支持添加非自动特征,如 Box<dyn Fn(usize) -> usize + Clone>
。
A closure is
Clone
orCopy
if it does not capture any values by unique immutable or mutable reference, and if all values it captures by copy or move areClone
orCopy
, respectively.
所以我觉得这个推导在理论上是有道理的,但是我暂时不知道能不能做到。
我不介意为 MyStruct
手动实现 Clone
,但我也不知道该怎么做。
我不想做类似
的事情#[derive(Clone)]
struct MyStruct<F: Fn(usize) -> usize> {
foo: F
}
因为这个结构被用作实现另一个特征结构的关联类型,而且那个结构和特征都没有泛型,我不想搞砸 PhantomData
.
扩展上面的@mcarton 评论,但使用 dyn-clone
板条箱来克服 Clone
不是对象安全的问题,代码非常简单。
use dyn_clone::DynClone;
trait FnClone: DynClone {
fn call(&self, x: usize) -> usize;
}
impl<F> FnClone for F
where F: Fn(usize) -> usize + Clone
{
fn call(&self, x: usize) -> usize {
self(x)
}
}
struct MyStruct {
foo: Box<dyn FnClone>
}
impl Clone for MyStruct {
fn clone(&self) -> MyStruct {
MyStruct {
foo: dyn_clone::clone_box(&*self.foo),
}
}
}
fn main() {
let a = MyStruct{
foo: Box::new(|x| x + 1)
};
let b = a.clone();
println!("{} {}", a.foo.call(1), b.foo.call(2));
}
这个 crate 还提供了一个宏 clone_trait_object!
来使 Clone
可以派生为 Box<dyn FnClone>
,但你似乎不希望这样。