2015-10-31 14 views
6

Ich habe eine Struktur mit einem Feld, das ein Funktionszeiger ist. Ich mag das Clone Merkmal für diese Struktur implementieren, aber ich kann nicht, weil Funktionszeiger kann nicht geklont werden, wenn sie mindestens einen Parameter haben:So klonen Sie einen Funktionszeiger

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.

Antwort

3

Das Problem ist nicht, dass Funktionszeiger im Allgemeinen nicht klonbar sind, aber dass Sie tatsächlich eine Funktion haben, die über die Lebensdauer des &str generisch ist. Zum Beispiel, wenn Sie die &str durch i32 ersetzen, wird Ihr Code kompilieren, weil i32 keine Lebenszeiten hat. In Ihrer Situation müssen Sie die Lebensdauer auf dem Funktionszeiger explizit machen:

type TypeFn<'a> = fn(s: &'a str); 

Das ist offensichtlich sprudelt auf die Struktur, auch:

#[derive(Clone)] 
struct MyStruct<'a> { 
    field: TypeFn<'a> 
} 

Dies verhindert, dass die folgende Art von Code:

let my_var = MyStruct{field: my_fn}; 
let s = String::new(); 
(my_var.field)(&s); 

Eigentlich ist das Problem, dass es ein Fehler ist. Wie in @MattBrubeck 's answer gezeigt, implementieren Funktionszeiger Copy. So können Sie einfach Clone manuell implementieren, indem Sie den Funktionszeiger des Copy impl:

impl Clone for MyStruct { 
    fn clone(&self) -> Self { 
     MyStruct { 
      field: self.field, 
     } 
    } 
} 
+0

macht mir nichts aus ... Die richtige Antwort ist, dass es ein Fehler ist ... Ich kann meinen eigenen Post zwar nicht ablehnen ^^ und ich kann keine Antwort löschen, die akzeptiert wurde ... –

+0

Ich habe die von http empfohlene Methode verwendet : //meta.stackoverflow.com/a/266154/1103681. Aber zögern Sie nicht, die angenommene Antwort zu ändern und einen Kommentar zu hinterlassen. Dann lösche ich meine Antwort. –

8

Funktionszeiger mit Referenzen in ihren Typen nicht umsetzen Clone wegen issue #24000. Dies bedeutet, dass Sie nicht für Typen verwenden können, die sie enthalten; Sie müssen es manuell implementieren.

Aber Funktionszeiger sindCopy, so können Sie impl Copy für Ihre Art und dann verwenden, um manuell impl Clone:

impl Copy for MyStruct {} 

impl Clone for MyStruct { 
    fn clone(&self) -> Self { *self } 
} 

Playpen link.

Verwandte Themen