2014-04-15 9 views
9

Sto imparando a proposito delle vite nominate in Rust e ho difficoltà a capire cosa rappresentano quando vengono utilizzate nell'implementazione di un tratto. In particolare, ho difficoltà a comprendere questa parte di codice da libserialize/hex.rs. Ho rimosso alcuni commenti per brevità.Che cosa fa un riferimento a vita una volta dichiarato in un'implementazione di tratto?

pub trait ToHex { 
    fn to_hex(&self) -> ~str; 
} 

static CHARS: &'static[u8] = bytes!("abcdef"); 

impl<'a> ToHex for &'a [u8] { 
    fn to_hex(&self) -> ~str { 
     let mut v = slice::with_capacity(self.len() * 2); 
     for &byte in self.iter() { 
      v.push(CHARS[(byte >> 4) as uint]); 
      v.push(CHARS[(byte & 0xf) as uint]); 
     } 

     unsafe { 
      str::raw::from_utf8_owned(v) 
     } 
    } 
} 

Capisco l''static vita nella definizione CHARS, ma stumped sulla durata definita nella realizzazione ToHex. Cosa rappresentano i tempi di vita nominati nell'implementazione di un tratto?

risposta

8

In quel caso particolare, non molto. &[u8] non è un tipo completamente specificato perché manca la durata e le implementazioni devono essere per i tipi completamente specificati. Pertanto, l'implementazione è parametrizzata rispetto all'arbitrario (per il parametro generico non vincolato) a vita 'a.

In questo caso, non lo si usa più. Ci sono casi in cui lo farai, tuttavia, quando desideri limitare un argomento di funzione o restituire un valore alla stessa durata.

È quindi possibile scrivere cose del genere:

impl<'a, T> ImmutableVector<'a, T> for &'a [T] { 
    fn head(&self) -> Option<&'a T> { 
     if self.len() == 0 { None } else { Some(&self[0]) } 
    } 
    … 
} 

Ciò significa che il valore di ritorno avrà la stessa vita come self, 'a.

Per inciso, tanto per complicare le cose, la durata potrebbe essere scritti manualmente su ogni funzione:

impl<'a, T> ImmutableVector<'a, T> for &'a [T] { 
    fn head<'a>(&'a self) -> Option<&'a T> { 
     if self.len() == 0 { None } else { Some(&self[0]) } 
    } 
    … 
} 

... e che dimostra che dover specificare la durata del tipo che si sta implementando per è solo in modo che il tipo sia effettivamente completamente specificato. E ti permette di scrivere un po 'meno per tutte le funzioni che usano quella vita.

+0

Impressionante, le cose ora hanno molto più senso per me. Ho ragione quando dico che * tutti i riferimenti richiedono una vita da definire *, ma che il compilatore lo aggiunge automaticamente in certi casi come gli argomenti delle funzioni? Penso che potrebbe essere la parte che mi mancava. – TwentyMiles

+0

In effetti, questo è il caso. Nella maggior parte dei casi viene determinato automaticamente se non specificato, e gli argomenti delle funzioni interne sono tali. –

+0

Il secondo esempio non è valido, poiché la durata del metodo oscura quella sull'imp? Oltre ad essere illegale nell'attuale ruggine, non è lo stesso. O mi sbaglio? Sono nuovo di Rust e non ho ancora compreso pienamente le vite. –

Problemi correlati