2015-06-26 4 views
11

se ho le due funzioniQuando è necessario specificare le durate esplicite in Rust?

// implicit 
fn foo(x: &i32) { 
} 

// explicit 
fn bar<'a>(x: &'a i32) { 
} 

In quale periodo foo restituiscono un errore e bar essere l'intestazione corretto funzionamento? Sono confuso da perché vorrei dichiarare in modo esplicito una vita:

L' 'una legge ‘la durata di un’. Tecnicamente, ogni riferimento ha una durata pari a associata ad esso, ma il compilatore consente di eliderli nei casi comuni .

Capisco quello che una vita è, ma ciò che specificare esplicitamente una vita 'afare per me? Per avere un riferimento sto usando il Rust book come materiale

risposta

10

In pratica, la ragione # 1 dovrete scrivere annotazioni a vita è a leggere perché il compilatore ti chiede così. Rifiuterà le firme delle funzioni che non sono coperte da lifetime elision rules.

Suppongo che ti piacerebbe un semplice esempio in cui le vite sono obbligatorie. Immaginate il seguente scenario:

struct Blah<'a> { 
    hoy: &'a u8 
} 

fn want_a_hoy(blah: &Blah) -> &u8 { 
    blah.hoy 
} 

L'intenzione è ovvio, ma il compilatore non gestirlo:

<anon>:7:35: 7:38 error: missing lifetime specifier [E0106] 
<anon>:7  fn want_a_hoy(blah: &Blah) -> &u8 { 
              ^~~ 
<anon>:7:35: 7:38 help: see the detailed explanation for E0106 
<anon>:7:35: 7:38 help: this function's return type contains a borrowed value, but 
         the signature does not say which one of `blah`'s 2 elided 
         lifetimes it is borrowed from 

In questo caso, le annotazioni risolvono il problema:

fn want_a_hoy<'a, 'b>(blah: &'b Blah<'a>) -> &'a u8 { 
    blah.hoy 
} 

Qui stai specificando 'a due volte (su Blah<'a> e &'a). Questa è la stessa vita! Quindi quello che stai dicendo al compilatore è: "Questa funzione si riferisce a un blah che contiene un riferimento interiore: restituirò qualcosa che vive esattamente come il riferimento interiore del blah". In questo caso, la firma dà un forte suggerimento che è probabile che tu possa restituire qualcosa che proviene dalle viscere del blah.

+4

Un esempio ancora più semplice in cui l'elisione a vita non riesce è 'fn pick_one (a: & T, b: & T) -> & T' (anche se restituisce sempre uno di questi in modo incondizionato). – delnan

+1

ha senso, grazie! –