es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Doble préstamo mutable en una declaración `if let` de Rust.

¿Por qué el siguiente código en Rust arroja un error de doble préstamo mutable?
Esperaría que el primer ámbito fuera el primer bloque, ya que los valores devueltos no pueden sobrevivir a este bloque, y el else if no se llamará si el primer if devuelve Some(arr).

if let Some(arr) = v.as_array_mut(){
 ...
} else if let Some(obj) = v.as_object_mut(){
 ...
} else {
 ...
}
    |
178 |                 if let Some(arr) = v.as_array_mut(){
    |                                    -------------------------- aquí ocurre el primer préstamo mutable
...
195 |                 } else if let Some(obj) = v.as_object_mut(){
    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                                           |
    |                                           aquí ocurre el segundo préstamo mutable
    |                                           el primer préstamo se utiliza después aquí

Por cierto, romper cada llamada en dos llamadas, lo cual proporciona un comportamiento similar obviamente no arroja un error:

if v.is_array(){
    let arr = v.as_array_mut().unwrap();
    ...
} else if v.is_object(){
    let obj = v.as_object_mut().unwrap();
    ...
} else {
    ...
}
Tags:  , ,

Answer

  1. Avatar for davy.ai

    El código en Rust muestra un error de doble préstamo mutable porque ambos bloques if y else if están intentando tomar prestado v de forma mutable al mismo tiempo. Esto viola las reglas de préstamo de Rust que impiden el aliasing de referencias mutables. El verificador de préstamos de Rust asegura que las referencias mutables a una variable no puedan existir al mismo tiempo, ya que esto puede conducir a carreras de datos y otros problemas de seguridad de memoria.

    En este caso, el primer préstamo mutable ocurre cuando se llama a v.as_array_mut(). El segundo préstamo mutable ocurre cuando se llama a v.as_object_mut() en el bloque else if, el cual intenta tomar prestado v de forma mutable mientras aún está siendo prestado de forma mutable en el primer bloque. El verificador de préstamos de Rust detecta esta situación y evita que el código se compile.

    El código alternativo que separa cada llamada en dos llamadas y utiliza unwrap() para obtener la referencia mutable por separado en cada bloque no genera un error de doble préstamo mutable porque v sólo se presta de forma mutable una vez en cada bloque.

Comments are closed.