En Rust hay dos tipos principales de referencias:
&T): proporcionan acceso solo de lectura.&mut T): permiten modificar el valor al que se refieren.Reglas:
Ejemplos de sintaxis:
fn read(val: &i32) { println!("{}", val); } fn write(val: &mut i32) { *val += 1; } let mut x = 5; read(&x); write(&mut x);
Pregunta: ¿Se pueden crear dos referencias mutables a una misma variable en diferentes ámbitos de una misma función?
Respuesta: No, incluso si las referencias se crean en bloques diferentes, el ámbito para el análisis de los préstamos abarca toda la función o variable, a menos que el compilador pueda demostrar con certeza que las referencias no se superponen. Esto a menudo resulta en errores de compilación:
let mut x = 10; let r1 = &mut x; { let r2 = &mut x; // ¡error! }
Historia
En el desarrollo de un parser, un desarrollador intentó almacenar simultáneamente una referencia mutable y una inmutable a un mismo buffer para optimizar la lectura y escritura. Como resultado, el código no compilaba, y tras "sortear" la regla a través de unsafe aparecieron errores de filtración de datos.
Historia
Al comenzar un proyecto de procesamiento de datos, uno de los participantes no realizaba "reanalyze borrow checker" para un código complejo con ámbitos anidados. Como resultado, debido a las referencias superpuestas, apareció el clásico error "cannot borrow as mutable because it's also borrowed as immutable" sin una indicación explícita en el código fuente del lugar del problema.
Historia
En el código multihilo se utilizaron referencias normales para acceder a datos compartidos. Al intentar cambiar los datos en hilos paralelos, se obtuvieron errores de compilador inesperados y condiciones de carrera al sortear el borrow checker a través de código inseguro.