En Rust, el concepto de propiedad es fundamental para garantizar la seguridad de la memoria y evitar errores comunes como los punteros colgantes. Sin embargo, hay situaciones en las que necesitamos acceder a los datos sin tomar posesión de ellos. Aquí es donde entran en juego las referencias y el préstamo.

Conceptos Clave

  1. Referencia: Una referencia permite acceder a un valor sin tomar posesión de él. Se denota con el símbolo &.
  2. Préstamo: El acto de crear una referencia a un valor se llama préstamo. Hay dos tipos de préstamos:
    • Préstamo Inmutable: Permite leer el valor pero no modificarlo.
    • Préstamo Mutable: Permite tanto leer como modificar el valor.

Préstamo Inmutable

Una referencia inmutable permite acceder a un valor sin modificarlo. Puedes tener múltiples referencias inmutables a un mismo valor al mismo tiempo.

Ejemplo

fn main() {
    let x = 5;
    let y = &x; // y es una referencia inmutable a x

    println!("El valor de x es: {}", x);
    println!("El valor de y es: {}", y);
}

Explicación

  • let y = &x; crea una referencia inmutable a x.
  • Puedes usar y para leer el valor de x, pero no puedes modificar x a través de y.

Préstamo Mutable

Una referencia mutable permite tanto leer como modificar el valor al que apunta. Solo puedes tener una referencia mutable a un valor en un momento dado.

Ejemplo

fn main() {
    let mut x = 5;
    let y = &mut x; // y es una referencia mutable a x

    *y += 1; // Modifica el valor de x a través de y

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

Explicación

  • let mut x = 5; declara x como mutable.
  • let y = &mut x; crea una referencia mutable a x.
  • *y += 1; desreferencia y y modifica el valor de x.

Reglas de Préstamo

  1. Puedes tener múltiples referencias inmutables a un valor.
  2. Solo puedes tener una referencia mutable a un valor.
  3. No puedes tener referencias inmutables y mutables al mismo tiempo.

Ejemplo de Error

fn main() {
    let mut x = 5;
    let y = &x; // Referencia inmutable
    let z = &mut x; // Error: no se puede tener una referencia mutable mientras hay una inmutable

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

Solución

fn main() {
    let mut x = 5;
    {
        let y = &x; // Referencia inmutable en un bloque separado
        println!("El valor de y es: {}", y);
    } // y deja de existir aquí

    let z = &mut x; // Ahora es seguro tener una referencia mutable
    *z += 1;

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

Ejercicios Prácticos

Ejercicio 1

Crea una función que tome una referencia inmutable a un entero y devuelva su doble.

fn doble(valor: &i32) -> i32 {
    // Tu código aquí
}

fn main() {
    let x = 10;
    let resultado = doble(&x);
    println!("El doble de {} es {}", x, resultado);
}

Solución

fn doble(valor: &i32) -> i32 {
    *valor * 2
}

fn main() {
    let x = 10;
    let resultado = doble(&x);
    println!("El doble de {} es {}", x, resultado);
}

Ejercicio 2

Crea una función que tome una referencia mutable a un entero y lo incremente en 1.

fn incrementar(valor: &mut i32) {
    // Tu código aquí
}

fn main() {
    let mut x = 10;
    incrementar(&mut x);
    println!("El valor incrementado es {}", x);
}

Solución

fn incrementar(valor: &mut i32) {
    *valor += 1;
}

fn main() {
    let mut x = 10;
    incrementar(&mut x);
    println!("El valor incrementado es {}", x);
}

Resumen

En esta sección, hemos aprendido sobre referencias y préstamos en Rust. Las referencias permiten acceder a los datos sin tomar posesión de ellos, y los préstamos pueden ser inmutables o mutables. Es crucial seguir las reglas de préstamo para evitar errores de compilación y garantizar la seguridad de la memoria. Con estos conceptos, estás mejor preparado para manejar la propiedad y el préstamo en Rust de manera efectiva.

© Copyright 2024. Todos los derechos reservados