2016-06-26 15 views
8

staram się uczynić ten prosty kod kompilacji:Funkcja rdzy nie ma trwałości statycznej?

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

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

Ale nie jest on z 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 

Jak to możliwe, że darmowa funkcja nie posiada żywotność statyczny? W jaki sposób ten kod może być niebezpieczny?

Odpowiedz

9

Rodzaj &dox nie jest &Fn(u8) -> u8 (lub nawet &fn(u8) -> u8), jest to jedynie coercible do&Fn(u8) -> u8. Dlatego właśnie bierzesz adres tymczasowy. Czasowniki nie są promowane do długości życia, nawet jeśli mogą w zasadzie być 'static. Na przykład ten kod również nie działa:

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

Istnieje kilka sposobów na obejście tego problemu. Normalnie można tylko jawnie utworzyć zmienną static i przyjąć odniesienie do tego:

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

w Twoim konkretnym przypadku, który nie działa bezpośrednio, ponieważ Fn(u8) -> u8 jest typem nieklejony (cecha konkretnie), więc nie można po prostu umieść to w static. Można to zrobić:

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

Jednak statyczną odniesienie do Fn* cecha obiektu jest raczej głupie rzeczy. Zamknięcia, które mogą być odniesieniami 'static są niezwykle rzadkie, więc możesz równie dobrze używać zwykłego typu fn(u8) -> u8 i ominąć całą działalność na całe życie.

Powiązane problemy