我有一个带有字段的结构,这是一个函数指针。我想为该结构实现Clone
特征,但我不能,因为如果函数指针至少有一个参数,则无法克隆它们:
fn my_fn(s: &str) {
println!("in my_fn {}", s);
}
type TypeFn = fn(s: &str);
#[derive(Clone)]
struct MyStruct {
field: TypeFn
}
fn main() {
let my_var = MyStruct{field: my_fn};
let _ = my_var.clone();
}
答案 0 :(得分:8)
由于issue #24000,其类型中带引用的函数指针不会实现Clone
。这意味着您无法#[derive(Clone)]
包含它们的类型;你必须手动实现它。
但是函数指针 Copy
,因此您可以impl Copy
为您的类型,然后使用它来手动impl Clone
:
impl Copy for MyStruct {}
impl Clone for MyStruct {
fn clone(&self) -> Self { *self }
}
答案 1 :(得分:3)
问题不在于函数指针通常不是可克隆的,而是实际上有一个函数在&str
的生命周期内是通用的。例如,如果将&str
替换为i32
,则代码将编译,因为i32
没有生命周期。在您的情况下,您需要使函数指针的生命周期显式:
type TypeFn<'a> = fn(s: &'a str);
这显然也会影响结构:
#[derive(Clone)]
struct MyStruct<'a> {
field: TypeFn<'a>
}
这可以防止以下类型的代码:
let my_var = MyStruct{field: my_fn};
let s = String::new();
(my_var.field)(&s);
实际上问题在于它是一个错误。如@MattBrubeck 's answer中所示,函数指针实现Copy
。因此,您可以使用函数指针&{39} Clone
impl手动实现Copy
:
impl Clone for MyStruct {
fn clone(&self) -> Self {
MyStruct {
field: self.field,
}
}
}