Lección 1

Ownership y movimientos

Comprende qué sucede cuando asignas, pasas o devuelves valores en Rust.

Nivel
Inicial
Duración
25 min
Actualizada

Por qué existe la propiedad

Un String reserva un buffer en el heap. Ese buffer debe liberarse una sola vez: si no se libera, se desperdicia memoria; si se libera dos veces o demasiado pronto, el programa puede acceder a memoria que ya no es válida.

Rust evita ese problema sin recolector de basura y sin exigir llamadas manuales a free. Cada valor tiene una única dueña —la variable que lo posee— y, cuando esa dueña sale de scope, Rust ejecuta drop y libera los recursos asociados.

Por eso let s2 = s1; no duplica el buffer de un String: transfiere su propiedad a s2 e invalida s1. Eso es un movimiento. Los tipos Copy sí se duplican de forma implícita; clone crea una duplicación explícita, y una referencia permite usar el valor temporalmente sin convertirse en su dueña.

Estado de la memoria

  • STACK · s1dueña · struct en stack
  • ptr0x1
  • len4
  • cap4
  • HEAP · 0x1h · o · l · a
01 / 06UNA DUEÑA

Qué cambia respecto a otros lenguajes

La misma asignación no expresa lo mismo en todos los lenguajes. Si a permite acceder a un valor que usa memoria dinámica, esto es lo habitual:

Lenguaje Al ejecutar b = a Liberación del recurso
TypeScript / Java Se copia una referencia gestionada. a y b permiten acceder al mismo objeto. El recolector de basura actúa cuando el objeto deja de ser alcanzable.
C++ Un tipo como std::string se copia. Para permitir un movimiento puede usarse b = std::move(a); después, a sigue siendo válido, pero su estado puede haber cambiado. Cada objeto libera sus recursos desde su destructor siguiendo RAII; normalmente no se usa delete directamente.
Rust Un tipo como String se mueve: b recibe el valor y a deja de poder utilizarse. Para duplicar también el buffer hay que escribir a.clone(). El recurso se libera mediante drop cuando sale de scope su dueña actual.

Rust sí permite varias referencias compartidas &T. Lo que el préstamo impide en código seguro es combinar acceso mutable con otros accesos al mismo valor: puede haber varias referencias compartidas o una referencia mutable, pero no ambas cosas a la vez. El compilador comprueba esta regla y también que ninguna referencia sobreviva al valor al que apunta.

Ejercicio 01 · Ownership

Completa dos funciones sin consumir los valores de entrada.

En ambas funciones solo necesitas leer los argumentos. Recíbelos por referencia, completa el código y ejecuta las pruebas.

0/2correctas

Implementa saludo_mas_largo para devolver uno de los textos recibidos por referencia. Implementa crear_saludo para generar un String nuevo sin consumir el argumento de entrada.

01

Implementa

Completa una función en cada editor.

Función 01

Seleccionar el texto más largo

Sin cambios

Recibe dos &str y devuelve el que tenga mayor longitud.

/// Devuelve el saludo más largo sin tomar la propiedad.
pub fn saludo_mas_largo(a: String, b: String) -> String {
    todo!("devuelve a o b")
}

Función 02

Construir un String nuevo

Sin cambios

Recibe un &str y crea un saludo sin consumir el valor de entrada.

/// Construye un saludo nuevo sin consumir el nombre.
pub fn crear_saludo(nombre: String) -> String {
    todo!("construye un String nuevo")
}
02

Comprueba

Ejecuta las pruebas y corrige el código a partir del diagnóstico de Rust.

devuelve el texto más largoel nombre sigue disponible
Compilador

Modifica el código antes de ejecutar las pruebas.

03

Ayuda

Consulta una pista o compara tu implementación con la solución.

Ejecuta un intento para desbloquear la solución.

Resumen

  • Cada valor tiene una única dueña (la variable que lo posee); al salir de scope, el valor se libera automáticamente.
  • Asignar o pasar un valor con datos en el heap mueve la propiedad; la variable anterior queda inválida.
  • clone() crea una copia profunda explícita cuando de verdad necesitas dos dueñas.
  • Los tipos Copy (sin heap) se copian en la asignación y ambas variables siguen vivas.
  • El compilador convierte los errores de memoria en errores de compilación con mensajes accionables.

Fuentes