2015-10-12 9 views
5

Ho il seguente programma Rust che passa una chiusura a una funzione generica in una vita 'a e una chiusura di tipo F, che chiama la chiusura con un riferimento ad alcuni dati locali:Il valore non vive abbastanza a lungo con una durata esplicita, ma vive abbastanza a lungo quando omesso

fn other_function<'a, F>(f: F) 
    where F: Fn(&'a u32) 
{ 
    let the_value = 0; 
    f(&the_value); 
} 

fn main() { 
    other_function(|_| { /* do nothing */ }); 
} 

Questo non riesce a compilare, con i seguenti messaggi:

<anon>:5:8: 5:17 error: `the_value` does not live long enough 
<anon>:5  f(&the_value); 
       ^~~~~~~~~ 
<anon>:3:1: 6:2 note: reference must be valid for the lifetime 'a as defined on the block at 3:0... 
<anon>:3 { 
<anon>:4  let the_value = 0; 
<anon>:5  f(&the_value); 
<anon>:6 } 
<anon>:4:23: 6:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 4:22 
<anon>:4  let the_value = 0; 
<anon>:5  f(&the_value); 
<anon>:6 } 
error: aborting due to previous error 
playpen: application terminated with error code 101 

il mio esempio minimale potrebbe essere un po 'troppo minimo ora, s per questo esempio, una soluzione valida è quella di rimuovere 'a, e 'a. Tuttavia, ho una situazione simile in un programma più complicato in cui sembrano necessarie vite esplicite.

Esiste un modo per specificare manualmente le durate, in modo tale che il programma sopra venga accettato dal compilatore?

risposta

6

Il problema è che il chiamante di other_function arriva a scegliere la vita che riempirà in 'a, ma si desidera other_function per farlo. Si potrebbe utilizzare un po 'di sintassi chiamato tratto più alto classificato limiti:

fn other_function<F>(f: F) 
    where F: for <'a> Fn(&'a u32) 
{ 
    let the_value = 0; 
    f(&the_value); 
} 

fn main() { 
    other_function(|_| { /* do nothing */ }); 
} 

Come lei ha sottolineato, in questo caso, ha più senso per omettere il 'a completamente. È possibile che il tuo caso abbia bisogno di qualcosa di più complicato, ma con il tuo esempio non ha senso nient'altro. Il chiamante non può specificare alcuna durata che sarà compatibile con una variabile allocata nello stack all'interno del metodo che stai chiamando.

+0

Ciò rende un carico di senso. Grazie per la chiara spiegazione. – Thierry

+0

Qual è il 'for' usato per lì? – Kroltan

+2

@Kroltan Quando stavo cercando di risolvere il mio problema, ho capito che dovevo in qualche modo fare in modo che 'Fn (& 'a u32)' fosse generico per un po' di vita ''a', ma non riuscivo a capire dove mettere esso. 'Fn <'a> (& 'a u32)' è ovviamente sbagliato. Per quanto ho capito, lo scopo di 'for' è esattamente quello di permettere di aggiungere una vita lì. – Thierry

Problemi correlati