Alias

Los datos se pueden tomar prestados de manera inmutable cualquier cantidad de veces, pero aunque se toman prestados de manera inmutable, los datos originales no se pueden tomar prestados de manera mutable. Por otro lado, solo se permite un préstamo mutable a la vez. Los datos originales se pueden volver a tomar prestados solo después de que se haya utilizado la referencia mutable por última vez.

struct Punto { x: i32, y: i32, z: i32 }

fn main() {
    let mut punto = Punto { x: 0, y: 0, z: 0 };

    let punto_prestado = &punto;
    let otro_prestamo = &punto;

    // Se puede acceder a los datos a través de las referencias y el propietario original
    println!("Punto tiene coordenadas: ({}, {}, {})",
             punto_prestado.x, otro_prestamo.y, punto.z);

    // ¡Error! No se puede pedir prestado `punto` como mutable porque actualmente está
    // prestado como inmutable.
    // let prestamo_mutable = &mut punto;
    // TODO ^ Intenta descomentar esta línea

    // Los valores prestados se vuelven a utilizar aquí
    println!("Punto tiene coordenadas: ({}, {}, {})",
             punto_prestado.x, otro_prestamo.y, punto.z);

    // Las referencias inmutables ya no se utilizan para el resto del código, por lo que
    // es posible renovar el préstamo con una referencia mutable.
    let prestamo_mutable = &mut punto;

    // Cambia datos mediante referencia mutable
    prestamo_mutable.x = 5;
    prestamo_mutable.y = 2;
    prestamo_mutable.z = 1;

    // ¡Error! No se puede pedir prestado `punto` como inmutable porque actualmente está
    // prestado como mutable.
    // let y = &punto.y;
    // TODO ^ Intenta descomentar esta línea

    // ¡Error! No se puede imprimir porque `println!` toma una referencia inmutable.
    // println!("Punto Z coordinate is {}", punto.z);
    // TODO ^ Intenta descomentar esta línea

    // ¡OK! Las referencias mutables se pueden pasar como inmutables a `println!`
    println!("Punto tiene coordenadas: ({}, {}, {})",
             prestamo_mutable.x, prestamo_mutable.y, prestamo_mutable.z);

    // La referencia mutable ya no se usa para el resto del código, por lo que
    // es posible renovar
    let nuevo_punto_prestado = &punto;
    println!("Punto ahora tiene coordenadas: ({}, {}, {})",
             nuevo_punto_prestado.x, nuevo_punto_prestado.y, nuevo_punto_prestado.z);
}