我有一个结构体,看起来像这样:
pub struct MyStruct<F>
where
F: Fn(usize) -> f64,
{
field: usize,
mapper: F,
// fields omitted
}
我该如何为这个结构体实现
Clone
?一种复制函数体的方法是:let mapper = |x| (mystruct.mapper)(x);
但这会导致
mapper
的类型与mystruct.mapper
不同。
我有一个结构体,看起来像这样:
pub struct MyStruct<F>
where
F: Fn(usize) -> f64,
{
field: usize,
mapper: F,
// fields omitted
}
Clone
?一种复制函数体的方法是:let mapper = |x| (mystruct.mapper)(x);
mapper
的类型与mystruct.mapper
不同。
从Rust 1.26.0版本开始,如果所有被捕获的变量都实现了Copy
和Clone
,那么闭包也会实现这两个trait:
#[derive(Clone)]
pub struct MyStruct<F>
where
F: Fn(usize) -> f64,
{
field: usize,
mapper: F,
}
fn main() {
let f = MyStruct {
field: 34,
mapper: |x| x as f64,
};
let g = f.clone();
println!("{}", (g.mapper)(3));
}
Clone
方法? - JohnClone
,编译器必须知道Clone
是什么。历史上,它并没有这样做。此外,其他特性呢?闭包也应该是Copy
吗?Eq
呢?你在哪里划线?我不认为有人真正确定应该在这里做什么。 - DK.fn(usize) -> f64
(一个“fn类型”)不是零大小,它相当于一个函数指针。fn(usize) -> f64 {::some::specific::function}
(一个“fn项类型”)是零大小的,但你不能写出那个类型,所以唯一的方法是通过接受一个通用类型 F: Fn(u64) -> f64 + Copy
来利用它(即,在问题的代码中添加一个“Copy”约束)。 - user395760F:Fn(..) - > .. + Copy
可能会使内联成为可能? - Johnfn
指定的大多数回调确实不太可能被内联。 - user395760您可以使用Rc
(或Arc
!)来获取同一不可克隆值的多个句柄。与Fn
(通过共享引用调用)闭包很好配合使用。
pub struct MyStruct<F> where F: Fn(usize) -> f64 {
field: usize,
mapper: Rc<F>,
// fields omitted
}
impl<F> Clone for MyStruct<F>
where F: Fn(usize) -> f64,
{
fn clone(&self) -> Self {
MyStruct {
field: self.field,
mapper: self.mapper.clone(),
...
}
}
}
请记住,#[derive(Clone)]
是一个非常有用的克隆模板,但在某些情况下它并不总是能够做出正确的事情;这就是其中之一。
您可以使用特质对象来实现对您的结构体进行克隆
:
use std::rc::Rc;
#[derive(Clone)]
pub struct MyStructRef<'f> {
field: usize,
mapper: &'f Fn(usize) -> f64,
}
#[derive(Clone)]
pub struct MyStructRc {
field: usize,
mapper: Rc<Fn(usize) -> f64>,
}
fn main() {
//ref
let closure = |x| x as f64;
let f = MyStructRef { field: 34, mapper: &closure };
let g = f.clone();
println!("{}", (f.mapper)(3));
println!("{}", (g.mapper)(3));
//Rc
let rcf = MyStructRc { field: 34, mapper: Rc::new(|x| x as f64 * 2.0) };
let rcg = rcf.clone();
println!("{}", (rcf.mapper)(3));
println!("{}", (rcg.mapper)(3));
}
I
是什么?这个无法编译。但是,如果F
没有返回任何内容,为什么不只使用#[derive(Clone)]
呢? - ljedrz