Guía de aprendizaje
Aprende Rust
Rust tiene fama de difícil. No lo es tanto: lo que pasa es que te obliga a entender desde el primer día algo que otros lenguajes esconden, quién es el dueño de cada dato en memoria. Esta guía empieza justo por ahí, con ejemplos que puedes ejecutar y esquemas que explican lo que el compilador está pensando.
La ruta de aprendizaje
Diez pasos, de la instalación a la concurrencia. Los dos primeros están explicados más abajo, en esta misma página; cada uno de los demás tiene su propia lección, con ejemplos que puedes copiar y ejecutar y esquemas como los de aquí. Si ya sabes qué buscas, entra directamente:
Concurrencia sin miedo
Hilos y canales, donde las reglas de préstamo rinden de verdad.
Leer lección →
Por qué Rust es distinto
Casi todos los lenguajes resuelven la gestión de memoria de una de dos formas. O te la dejan a ti, como C y C++, y entonces los errores de memoria son tuyos: punteros colgantes, fugas, accesos después de liberar. O la resuelve un recolector de basura que corre mientras el programa funciona, como en Java, Python o Go, y entonces pagas en rendimiento y en pausas impredecibles.
Rust propone una tercera vía: comprobar en tiempo de compilación que el uso de la memoria es correcto. Si el programa compila, no tendrá esa clase de errores. No hay recolector de basura, no hay pausas, y tampoco hay que acordarse de liberar nada.
El precio es que el compilador te va a decir que no bastantes veces al principio. La buena noticia es que casi siempre tiene razón, y que hay solo tres ideas que hay que entender para que deje de pelearse contigo.
La primera idea: cada valor tiene un dueño
En Rust, cada dato en memoria pertenece a una variable, y solo a una. Cuando esa variable desaparece, el dato se libera. Automáticamente, sin recolector.
De ahí sale la regla que más sorprende al llegar de otros lenguajes: si asignas una variable a otra, el valor se mueve. La original deja de ser válida.
fn main() {
let a = String::from("hola");
let b = a; // el valor se mueve de a hacia b
println!("{b}"); // correcto
// println!("{a}"); // error: a ya no es válida
}
Esto parece una molestia y en realidad es la pieza central. Si solo hay un dueño, el compilador sabe exactamente cuándo puede liberar la memoria, y sabe que nadie más va a intentar usarla después. De ahí salen gratis dos cosas que en otros lenguajes cuestan caro: no hay fugas y no hay accesos a memoria ya liberada.
La segunda idea: prestar en lugar de mover
Mover el valor cada vez sería insufrible. Por eso Rust permite prestarlo: pasar una referencia sin ceder la propiedad. Se escribe con &.
fn longitud(s: &str) -> usize {
s.len()
}
fn main() {
let texto = String::from("hola mundo");
let n = longitud(&texto); // se presta, no se mueve
println!("{texto} tiene {n} caracteres"); // texto sigue siendo válida
}
Los préstamos tienen una sola regla, y entenderla resuelve la mayoría de los errores del principio: puedes tener muchos lectores o un único escritor, pero nunca las dos cosas a la vez.
fn main() {
let mut mensaje = String::from("hola");
let r1 = &mensaje; // lector
let r2 = &mensaje; // otro lector, sin problema
println!("{r1} {r2}");
let r3 = &mut mensaje; // escritor: ahora no puede haber lectores vivos
r3.push_str(", mundo");
println!("{r3}");
}
La tercera idea: los errores son valores
Rust no tiene excepciones. Una función que puede fallar devuelve un Result, y el compilador te obliga a decidir qué hacer con él. No se puede ignorar por descuido.
use std::fs;
fn main() {
match fs::read_to_string("datos.txt") {
Ok(contenido) => println!("{contenido}"),
Err(e) => eprintln!("No se pudo leer el archivo: {e}"),
}
}
Lo mismo ocurre con la ausencia de valor: no hay null. Lo que puede no existir se envuelve en un Option, y hay que abrirlo explícitamente. Es la razón por la que en Rust no existe el error más caro de la historia del software, la desreferencia de null.
Tu primer programa
Rust se instala con rustup, que trae el compilador y Cargo, que es a la vez gestor de paquetes y sistema de construcción. En Linux o macOS:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
En Windows se descarga el instalador desde rustup.rs. Al terminar, comprueba que todo está en su sitio:
rustc --version cargo --version
Ahora el primer proyecto. Cargo crea la estructura, las dependencias y el repositorio de un tirón:
cargo new hola cd hola cargo run
Eso ya imprime «Hello, world!». El archivo que lo hace es src/main.rs:
fn main() {
println!("Hola, mundo");
}
Dos detalles que conviene notar desde el principio. main es la función por la que empieza todo, como en C o Java. Y println! lleva un signo de exclamación porque no es una función sino una macro: código que se expande en tiempo de compilación. En Rust verás bastantes.
Dónde seguir mientras tanto
Las fuentes oficiales son excelentes y gratuitas. The Rust Programming Language, conocido como «el libro», es la referencia completa. Rust by Example enseña a base de código comentado y ejecutable. Y el playground permite compilar y ejecutar Rust en el navegador, sin instalar nada: es el sitio ideal para probar los ejemplos de esta guía antes de montar un proyecto.
Si vienes de otro lenguaje, el consejo que más ahorra tiempo es este: no intentes escribir Rust como escribirías Java o Python. Muchas peleas con el compilador vienen de trasladar patrones que aquí no encajan. Dale unos días a la forma de pensar del lenguaje y la resistencia desaparece.
Si prefieres verlo en vídeo

«Curso de RUST Desde Cero: Primeros Pasos en una hora», del canal MoureDev by Brais Moure (1:14:39). Recorre en una sentada el terreno que cubre esta guía y las primeras lecciones, así que sirve bien como primera pasada antes de leer, o como repaso después. Material de otro canal que recomendamos como complemento, no una producción de decodigo.com. El reproductor solo se carga al pulsar, así que YouTube no recibe nada tuyo hasta entonces. También puedes verlo en YouTube.