ProgrammazioneSviluppatore Rust Backend

Spiega come funziona il borrowing e l'aliasing in Rust. Quali sono le limitazioni sull'uso simultaneo di riferimenti mutabili e immutabili, come viene controllato dal compilatore e cosa può andare storto?

Supera i colloqui con l'assistente IA Hintsage

Risposta

Il borrowing in Rust è un meccanismo di "prestito" temporaneo di una variabile tramite riferimenti. Rust distingue tra borrowing immutabile (&T) e mutabile (&mut T). Possono esistere quanti più riferimenti immutabili contemporaneamente, ma solo uno mutabile. Non è consentita l'esistenza simultanea di riferimenti mutabili e immutabili allo stesso oggetto.

Questa regola garantisce l'assenza di data race in fase di compilazione e rende Rust sicuro per la programmazione concorrente.

Esempio:

let mut value = 5; let r1 = &value; let r2 = &value; // let r3 = &mut value; // ERRORE: non si può creare &mut finché ci sono & println!("{} {}", r1, r2); // r3 è vietato fino alla fine della visibilità di r1/r2

Domanda trabocchetto

Domanda: È possibile creare un riferimento &mut e quanti più riferimenti & su un oggetto nella stessa area di visibilità?

Risposta errata tipica: Sì, ma solo se non si sovrappongono nella durata.

Risposta corretta: Non può esistere simultaneamente un riferimento mutabile e uno immutabile allo stesso oggetto (anche se gli accessi non si sovrappongono staticamente nel codice), mentre uno è vivo — gli altri sono vietati. La sicurezza è verificata dal borrow checker.

Esempio:

let mut x = 10; let y = &x; let z = &mut x; // Errore, y è ancora nell'area di visibilità println!("{}", y); // y è necessario più tardi

Esempi di errori reali a causa della mancanza di conoscenza delle sfumature dell'argomento


Storia

In un grande progetto di elaborazione parallela dei dati, uno sviluppatore ha deciso di utilizzare riferimenti immutabili a un vettore e poi ha cercato di ottenere un mutabile per ordinare. Il codice funzionava nel test, ma ha smesso di compilarsi dopo il refactoring, poiché è aumentato il tempo di vita dei riferimenti immutabili.


Storia

In un servizio interno, modificavano la struttura tramite &mut, mantenendo allo stesso tempo riferimenti ai campi per ulteriori invii in un altro thread. Si è verificata una data race e un crash a causa della violazione delle regole di borrowing — Rust protegge da questo solo in fase di compilazione, ma gli errori si sono verificati in blocchi unsafe, dove le garanzie sono state rimosse.


Storia

Documentazione API scorretta: la libreria accettava contemporaneamente & e &mut su diversi campi della struttura, ma a causa dell'aliasing venivano violate le invarianti, causando bug difficili da individuare con i servizi che integravano questa libreria.