[英]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>
。
從銹參考:
閉包是
Clone
或Copy
,如果它不捕捉唯一不變或可變引用任何價值,如果它通過捕獲復制或移動所有值都Clone
或Copy
分別。
所以我認為這個推導在理論上是有道理的,但我現在不知道我是否可以做到。
我不介意為MyStruct
手動實現Clone
,但我也不知道該怎么做。
我不想做類似的事情
#[derive(Clone)]
struct MyStruct<F: Fn(usize) -> usize> {
foo: F
}
因為這個結構被用作一個關聯類型來實現另一個結構的特征,並且該結構和特征都沒有泛型,我不想弄亂PhantomData
。
擴展上面的@mcarton 評論,但使用dyn-clone
crate 來克服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!
使Box<dyn FnClone>
的Clone
可Box<dyn FnClone>
,但您似乎不想要那樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.