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
- Referencia: Una referencia permite acceder a un valor sin tomar posesión de él. Se denota con el símbolo
&
. - 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 ax
.- Puedes usar
y
para leer el valor dex
, pero no puedes modificarx
a través dey
.
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;
declarax
como mutable.let y = &mut x;
crea una referencia mutable ax
.*y += 1;
desreferenciay
y modifica el valor dex
.
Reglas de Préstamo
- Puedes tener múltiples referencias inmutables a un valor.
- Solo puedes tener una referencia mutable a un valor.
- 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.
Curso de Programación en Rust
Módulo 1: Introducción a Rust
- ¿Qué es Rust?
- Configuración del Entorno de Rust
- Programa "Hola, Mundo!"
- Sintaxis y Estructura Básica