ProgrammazioneSviluppatore Backend

Descrivi i diversi tipi di riferimenti in Rust: le differenze tra riferimenti mutabili e non mutabili, le regole di esclusività e durata, e come scrivere correttamente funzioni che accettano diversi tipi di riferimenti. Fornisci esempi di sintassi e parla degli errori tipici nella gestione dei riferimenti.

Supera i colloqui con l'assistente IA Hintsage

Risposta

In Rust esistono due tipi principali di riferimenti:

  • Riferimenti non mutabili (&T): forniscono accesso in sola lettura.
  • Riferimenti mutabili (&mut T): consentono di modificare il valore a cui si riferiscono.

Regole:

  • Possono esistere contemporaneamente un numero qualsiasi di riferimenti non mutabili o solo un riferimento mutabile; non è possibile mescolarli nello stesso ambito.
  • I riferimenti hanno una durata (lifetime) che viene analizzata in fase di compilazione.

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 trabocchetto

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! }

Esempi di errori reali dovuti alla scarsa conoscenza dell'argomento


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.