2016-06-26 4 views
8

Я пытаюсь сделать этот простой код компиляции:Функция ржавчины не имеет статического времени жизни?

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

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

Но он терпит неудачу с 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 

Как это возможно, что свободная функция не имеет статическую жизни? Как этот код может быть небезопасным?

ответ

9

Тип &dox не &Fn(u8) -> u8 (или даже &fn(u8) -> u8), это просто сжимаемого в&Fn(u8) -> u8. Таким образом, вы фактически принимаете адрес временного. Тем не менее, тем не менее, тем не менее, тем не менее, тем не менее, тем не менее, тем не менее, тем не менее, тем не менее, тем не менее, тем не менее, Например, этот код не работает:

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

Для этого есть некоторые способы обхода пути. Обычно можно просто явно создать static переменную и взять ссылку на что:

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

В вашем конкретном случае, который не работает напрямую, потому что Fn(u8) -> u8 является несортированный типа (черта, в частности), так что вы не можете просто поставьте это в static. Вы можете сделать это:

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

Однако статическая ссылка на Fn* объекта признака довольно глупо. Закрытия, которые могут быть ссылками 'static, встречаются крайне редко, поэтому вы можете просто использовать простой тип fn(u8) -> u8 и обойти весь жизненный бизнес.