Le strutture in Rust possono contenere riferimenti ad altri oggetti specificando esplicitamente le durate (lifetimes) nella definizione della struttura. Questo è necessario affinché il compilatore possa verificare che nessun riferimento diventi invalido. Ecco un esempio:
struct Book<'a> { title: &'a str, author: &'a str, }
Qui la struttura Book contiene due riferimenti con la stessa durata 'a. Quando scrivi una funzione che restituisce tale struttura, devi garantire che tutti i riferimenti siano validi indipendentemente dalla logica interna della funzione:
fn book_factory<'a>(title: &'a str, author: &'a str) -> Book<'a> { Book { title, author } }
Se tenti di restituire dalla funzione una struttura in cui i campi di riferimento puntano, ad esempio, a variabili locali di quella funzione, si verificherà un errore di compilazione, poiché la durata dei riferimenti non è sufficiente per un accesso sicuro.
È possibile creare una struttura che in uno dei suoi campi contiene un riferimento (&str) e nell'altro un String? Perché questo potrebbe essere un problema?
La risposta errata comune è: "Sì, è possibile, è sicuro".
In realtà, se &str è stato ottenuto da String e la struttura supera questa String, il riferimento diventerà dangling (riferimento pendente). Ad esempio:
struct Test<'a> { s1: &'a str, s2: String, } fn main() { let s = String::from("hello"); let t = Test { s1: &s, s2: s }; // t.s1 è, di fatto, sicuro solo finché s2 (s) è vivo, ma se s2 viene rimosso per primo — errore }
Storia In un progetto hanno tentato di restituire da una funzione di caricamento una struttura contenente un riferimento a una stringa temporanea, creata all'interno della stessa funzione. Il codice non è stato compilato, e ci è voluto un notevole ripensamento per rimuovere la durata della variabile locale.
Storia Uno sviluppatore intendeva utilizzare una struttura con un riferimento a un elemento di un array, creato nella funzione, ma dopo il ritorno questo riferimento si è rivelato non valido, il che è stato correttamente prevenuto dal compilatore.
Storia In un progetto aziendale, gli sviluppatori hanno conservato un riferimento &str a una stringa di un altro oggetto, che era stato rimosso dalla collezione prima del riferimento stesso — quando si è tentato di accedere a questo riferimento, è avvenuto un panic.