In Rust esistono due tipi principali di riferimenti:
&T): forniscono accesso in sola lettura.&mut T): consentono di modificare il valore a cui si riferiscono.Regole:
Esempi di sintassi:
fn read(val: &i32) { println!("{}", val); } fn write(val: &mut i32) { *val += 1; } let mut x = 5; read(&x); write(&mut x);
Domanda: È possibile creare due riferimenti mutabili su una variabile in diversi ambiti all'interno di una stessa funzione?
Risposta: No, anche se i riferimenti vengono creati in blocchi diversi, l'ambito per l'analisi dei prestiti copre l'intera funzione o variabile, se il compilatore non può dimostrare con certezza che i riferimenti non si sovrappongono. Questo porta spesso a errori di compilazione:
let mut x = 10; let r1 = &mut x; { let r2 = &mut x; // errore! }
Storia
Nello sviluppo di un parser, un sviluppatore ha tentato di memorizzare simultaneamente un riferimento mutabile e uno non mutabile su uno stesso buffer per ottimizzare la lettura e la scrittura. Di conseguenza, il codice non si compilava e dopo aver "aggirato" la regola attraverso unsafe sono emersi bug di perdita di dati.
Storia
All'inizio di un progetto di elaborazione dati, uno dei membri non ha eseguito il "reanalyze borrow checker" per un codice complesso con ambiti annidati. Di conseguenza, a causa di riferimenti sovrapposti, è emerso il classico errore "cannot borrow as mutable because it's also borrowed as immutable" senza un'indicazione chiara nel codice sorgente del luogo del problema.
Storia
Nel codice multithreading sono stati utilizzati riferimenti normali per accedere a dati condivisi. Nel tentativo di modificare i dati in flussi paralleli, si ricevevano errori di compilazione imprevisti e condizioni di gara quando si aggirava il borrow checker tramite codice non sicuro.