Debido a las circunstancias actuales, el seminario de Rust se realizará de manera online y virtual. Esta guía proporciona todo lo necesario para que los alumnos puedan seguir el seminario de forma autónoma.
El objetivo es proporcionar una guía estructurada para aprender Rust utilizando el libro oficial como referencia principal. No se espera que los alumnos se conviertan en expertos en Rust, sino que comprendan los conceptos clave que hacen del lenguaje una herramienta adecuada para la programación concurrente.
Rust es un lenguaje de programación de sistemas moderno, diseñado con dos objetivos principales: seguridad y eficiencia. Se presenta como una alternativa a C y C++ en contextos donde el control sobre la memoria y el rendimiento son fundamentales, pero al mismo tiempo elimina gran parte de los errores comunes asociados a estos lenguajes.
En particular, Rust destaca por:
- Permitir el control de bajo nivel de la memoria, como en C/C++.
- Garantizar seguridad en memoria gracias a comprobaciones en tiempo de compilación.
- Evitar errores clásicos como null pointer dereference, dangling pointers, use-after-free o data races.
Problemas de lenguajes tradicionales
C y C++ han sido durante décadas los lenguajes de referencia para la programación de sistemas y aplicaciones de alto rendimiento. Sin embargo, presentan limitaciones importantes que complican la escritura de programas seguros y concurrentes:
-
Gestión manual de memoria:
El programador debe reservar y liberar memoria explícitamente. Esto conduce a errores frecuentes como:- Memory leaks (fugas de memoria): Ocurre cuando se reserva memoria dinámica (
malloc
onew
) pero nunca se libera (free
odelete
). Ejemplo:
void main() { int* p = new int[10]; } // acaba el proceso y se olvida delete[] p;
Esto provoca consumo innecesario de memoria y puede degradar el rendimiento.
- Dangling pointers (punteros colgantes): Se produce cuando un puntero apunta a una dirección de memoria que ya ha sido liberada. Ejemplo:
int* p = new int(5); delete p; *p = 10; // acceso inválido, puntero colgante
- Use-after-free (uso de memoria ya liberada): Similar al anterior, pero con efectos más sutiles y peligrosos, especialmente en programas concurrentes. Ejemplo:
int* p = new int(42); delete p; printf("%d", *p); // comportamiento indefinido
- Memory leaks (fugas de memoria): Ocurre cuando se reserva memoria dinámica (
-
Falta de comprobaciones en compilación:
Muchos errores relacionados con la memoria y la concurrencia se detectan únicamente en tiempo de ejecución, provocando fallos difíciles de depurar. -
Concurrencia insegura por defecto:
En C++ es posible que múltiples hilos accedan a la misma región de memoria sin la debida sincronización. Esto genera:- Data races (condiciones de carrera).
- Comportamientos indefinidos que dependen del sistema o del hardware.
- Errores intermitentes difíciles de reproducir.
-
Complejidad creciente en la depuración:
Aunque C++ ha incorporado bibliotecas modernas (comostd::thread
ostd::atomic
), el lenguaje sigue permitiendo combinaciones peligrosas que no son bloqueadas por el compilador.
C y C++ ofrecen flexibilidad y control, pero a costa de una gran fragilidad. El programador debe estar constantemente alerta para evitar errores de memoria y concurrencia. Rust surge precisamente para resolver estos problemas: mantiene el rendimiento de C/C++ pero añade un sistema de tipos y reglas de propiedad que impiden compilar programas inseguros.
Relevancia para la asignatura
En el contexto de la programación concurrente, Rust es especialmente interesante porque su sistema de propiedad (ownership) y préstamo (borrowing) impide que dos hilos accedan a la misma región de memoria de forma insegura. El compilador se asegura de que el acceso concurrente esté correctamente sincronizado antes de que el programa se ejecute.
Esto significa que:
- Muchos errores que en C, C++ o Java aparecen en tiempo de ejecución, en Rust son imposibles de compilar.
- La concurrencia deja de ser un problema “difícil de depurar” y pasa a ser una propiedad garantizada por el diseño del lenguaje.
- Los estudiantes pueden concentrarse en el modelo de concurrencia y no tanto en evitar errores de memoria.
En este sentido, Rust nos proporciona un marco ideal para aprender los fundamentos de la programación concurrente de forma práctica y segura.
Material de referencia
En este seminario nos centraremos en los siguientes materiales:
- Libro oficial de Rust (The Rust Book): https://doc.rust-lang.org/book/
- Ejercicios de Rustlings: https://rustlings.rust-lang.org/
- Documentación oficial de Rust: https://doc.rust-lang.org/
Tareas
En esta primera sesión, nos centraremos en los siguientes aspectos fundamentales:
- Instalación de Rust y Cargo.
- Aspectos básicos del lenguaje: variables, bucles y condiciones.
- El modelo de propiedad (ownership) y préstamos (borrowing).
- Funciones y ámbitos.
- Structs, Enums y el Pattern matching, una propiedad muy potente de Rust.
Se realizarán las siguientes tareas:
-
Lectura de los siguientes capítulos del libro de Rust:
- Capítulo 1: Getting Started
- Capítulo 2: Programming a Guessing Game
- Capítulo 3: Common Programming Concepts
- Capítulo 4: Understanding Ownership
- Capítulo 5: Using Structs to Structure Related Data
- Capítulo 6: Enums and Pattern Matching
-
Realización de los ejercicios del 0 al 10 de Rustlings. Estos ejercicios no se tienen que entregar pero es muy recomendable realizarlos para familiarizarse de manera práctica con el lenguaje. Son ejercicios muy sencillos y rápidos de hacer que permiten ejemplificar los aspectos aprendidos en el libro. Es recomendable realizarlos en paralelo a la lectura del libro.