No puedo acceder a un valor de una referencia compartida mutable en Rust

Publicado por Brisa
hace 5 meses

Hola a todos,

Estoy trabajando en un proyecto en Rust y estoy teniendo problemas para acceder a un valor de una referencia compartida mutable. He estado investigando sobre préstamos y referencias en Rust, pero aún no logro resolver mi problema.

Aquí está el código fuente que estoy utilizando:

fn main() {
    let mut numero = 5;
    let referencia = &mut numero;

    cambiar_valor(referencia);

    println!("El valor es: {}", referencia);
}

fn cambiar_valor(valor: &mut i32){
    *valor = 10;
}

Cuando intento compilar este código, obtengo el siguiente error:

error[E0502]: cannot borrow `*valor` as mutable because `valor` is also borrowed as immutable
 --> src/main.rs:9:5
  |
7 |     let referencia = &mut numero;
  |                      ---------- immutable borrow occurs here
8 | 
9 |     cambiar_valor(referencia);
  |     ^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
10|
11|     println!("El valor es: {}", referencia);
  |                                  ---------- immutable borrow later used here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
error: Could not compile `playground`.

To learn more, run the command again with --verbose.

Entiendo que no puedo acceder al valor a través de la referencia compartida mutable porque ya tengo una referencia inmutable a numero. Sin embargo, no estoy seguro de cómo solucionar este problema.

¿Alguien puede ayudarme a entender cómo puedo acceder a este valor de referencia compartida mutable sin obtener un error?

¡Gracias de antemano por cualquier ayuda que puedan brindarme!

rust mutable
Respuesta de Gordon Shumway
hace 5 meses

¡Hola Brisa!

El error que estás experimentando no se debe a que estés tratando de acceder a numero a través de una referencia mutable mientras tienes una referencia inmutable (lo cual también es un error), sino a que Rust no permite aliasing mutable, es decir, no puedes tener más de una referencia mutable al mismo dato en un mismo ámbito, ni tampoco mezclar referencias mutables e inmutables.

El mensaje de error te indica que estás intentando tomar una referencia mutable en cambiar_valor(referencia), lo cual no está permitido porque ya se tomó una referencia mutable anteriormente cuando se creó la variable referencia.

El código que escribiste en realidad no contiene el error de mezcla de referencias mutables e inmutables que el mensaje de error describe, se trata de un error en la descripción del error.

Para corregir esto en tu ejemplo de código, simplemente debes asegurarte de no usar referencia después de haber llamado a cambiar_valor, así que puedes imprimir el valor directamente de numero en lugar de referencia. Rust permite recuperar el control total sobre numero después de que la referencia mutable haya dejado de ser usada (es decir, cuando cambiar_valor retorna).

Aquí tienes el código corregido:

fn main() {
    let mut numero = 5;
    let referencia = &mut numero;

    cambiar_valor(referencia);

    // Imprime el valor directamente a través de `numero`.
    println!("El valor es: {}", numero);
}

fn cambiar_valor(valor: &mut i32) {
    *valor = 10;
}

Así, al llamar a cambiar_valor, pasas la referencia mutable y después ya no la utilizas. A partir de ese momento, puedes usar numero directamente, puesto que la referencia mutable ya no está en uso y Rust te permite volver a tomar propiedad de numero.