如何克隆函数指针

时间:2015-10-31 17:25:13

标签: 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();
}

Link to playground

2 个答案:

答案 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 }
}

Playpen link

答案 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,
        }
    }
}