如何克隆函数指针

Moe*_*ius 7 rust

我有一个结构,其中一个字段是一个函数指针.我想实现该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();
}
Run Code Online (Sandbox Code Playgroud)

链接到游乐场.

Mat*_*eck 8

Clone由于问题#24000,在其类型中具有引用的函数指针未实现.这意味着你不能#[derive(Clone)]用于包含它们的类型; 你必须手动实现它.

但是函数指针 Copy,所以你可以impl Copy为你的类型,然后手动使用它impl Clone:

impl Copy for MyStruct {}

impl Clone for MyStruct {
    fn clone(&self) -> Self { *self }
}
Run Code Online (Sandbox Code Playgroud)

围栏链接.


oli*_*obk 4

问题不在于函数指针通常是不可克隆的,而是您实际上拥有一个在&str. 例如,如果您将 替换&stri32您的代码将编译,因为i32没有生命周期。在您的情况下,您需要明确函数指针的生命周期:

type TypeFn<'a> = fn(s: &'a str);
Run Code Online (Sandbox Code Playgroud)

这显然也冒泡到结构中:

#[derive(Clone)]
struct MyStruct<'a> {
    field: TypeFn<'a>
}
Run Code Online (Sandbox Code Playgroud)

这可以防止以下类型的代码:

let my_var = MyStruct{field: my_fn};
let s = String::new();
(my_var.field)(&s);
Run Code Online (Sandbox Code Playgroud)

事实上,问题在于它是一个错误。如@MattBrubeck 的答案所示函数指针实现Copy。所以你可以Clone通过使用函数指针的Copyimpl 手动实现:

impl Clone for MyStruct {
    fn clone(&self) -> Self {
        MyStruct {
            field: self.field,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)