I have a structure with a field which is a function pointer. I want to implement the Clone
trait for that struct, but I can't because function pointers can't be cloned if they have at least one parameter:
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.
Function pointers with references in their types don't implement Clone
because of issue #24000. This means that you can't #[derive(Clone)]
for types containing them; you have to implement it manually.
But function pointers are Copy
, so you can impl Copy
for your type and then use that to manually impl Clone
:
impl Copy for MyStruct {}
impl Clone for MyStruct {
fn clone(&self) -> Self { *self }
}
Playpen link.
The problem is not that function pointers in general are not clonable, but that you actually have a function that is generic over the lifetime of the &str
. For example if you replace the &str
with i32
your code will compile, because i32
has no lifetimes. In your situation you need to make the lifetimes on the function pointer explicit:
type TypeFn<'a> = fn(s: &'a str);
This obviously bubbles up to the struct, too:
#[derive(Clone)]
struct MyStruct<'a> {
field: TypeFn<'a>
}
This prevents the following kind of code:
let my_var = MyStruct{field: my_fn};
let s = String::new();
(my_var.field)(&s);
Actually the problem is that it's a bug. As shown in @MattBrubeck 's answer Function pointers implement Copy
. So you can just implement Clone
manually by using the function pointer's Copy
impl:
impl Clone for MyStruct {
fn clone(&self) -> Self {
MyStruct {
field: self.field,
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With