2016-06-26 19 views
8

Ich versuche, diese einfache Code-Kompilierung zu machen:Rostfunktion hat keine statische Lebensdauer?

fn dox(x: u8) -> u8 { x*2 } 

fn main() { 
    let cb: &'static (Fn(u8) -> u8) = &dox; 
} 

aber es funktioniert nicht mit Rust 1,9:

x.rs:4:40: 4:43 error: borrowed value does not live long enough 
x.rs:4  let cb: &'static (Fn(u8) -> u8) = &dox; 
               ^~~ 
note: reference must be valid for the static lifetime... 
x.rs:4:44: 5:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 4:43 
x.rs:4  let cb: &'static (Fn(u8) -> u8) = &dox; 
x.rs:5 } 
error: aborting due to previous error 

Wie ist es möglich, dass eine freie Funktion nicht statisch Lebensdauer hat? Wie könnte dieser Code unsicher sein?

Antwort

9

Die Art der &dox ist nicht &Fn(u8) -> u8 (oder sogar &fn(u8) -> u8), es ist lediglich coercible zu&Fn(u8) -> u8. Daher nehmen Sie tatsächlich die Adresse eines temporären. Provisorien werden nicht auf 'static Lebenszeit heraufgestuft, auch wenn sie im Prinzip 'static sein könnten. Zum Beispiel funktioniert dieser Code auch nicht:

fn main() { 
    let a: &'static i32 = &5; 
} 

Es gibt einige Problemumgehungen dafür. Normalerweise kann man nur explizit eine static Variable erstellen und den Verweis auf das nehmen:

fn main() { 
    static FIVE: i32 = 5; 
    let a: &'static i32 = &FIVE; 
} 

In Ihrem speziellen Fall, das nicht direkt arbeiten, weil Fn(u8) -> u8 ein unsized Typ (ein Merkmal, speziell), so kann man nicht setzen Sie das einfach in eine static. Sie können dies tun:

fn main() { 
    static DOX: fn(u8) -> u8 = dox; // note: fn, not Fn 
    let a: &'static Fn(u8) -> u8 = &DOX; 
} 

jedoch eine statische Referenz auf ein Fn* Merkmale Objekt eine ziemlich dumme Sache ist. Verschlüsse, die 'static Referenzen sein können, sind extrem selten, so dass Sie einfach eine einfache fn(u8) -> u8 Art verwenden und das gesamte Lebensgeschäft umgehen können.