let x = 5; Enlace de variable inmutable
let mut x = 5; Enlace de variable mutable
const MAX: u32 = 100; Constante en tiempo de compilación
let x: i32 = 10; Anotación de tipo explícita
i8 i16 i32 i64 i128 isize
u8 u16 u32 u64 u128 usize Tipos enteros (con/sin signo)
f32 f64 Tipos de punto flotante
let s = String::from("hello"); Cadena alojada en el heap
let s: &str = "hello"; Porción de cadena (referencia prestada)
let arr = [1, 2, 3]; Array de tamaño fijo
let tup: (i32, f64, &str) = (1, 2.0, "hi"); Tupla con tipos mixtos
if condition {
...
} else if other {
...
} else {
...
} If/else (expresión, no sentencia)
for item in &vec { ... } Bucle for sobre iterador
loop { break; } Bucle infinito con break explícito
while condition { ... } Bucle while
println!("x = {x}, y = {}", y); Imprimir con macros de formato
let s2 = s1; Mover propiedad (s1 es inválido después)
let s2 = s1.clone(); Copia profunda (ambos siguen válidos)
fn take(s: String) { ... } La función toma propiedad del argumento
fn borrow(s: &String) { ... } Préstamo inmutable (referencia)
fn mutate(s: &mut String) { ... } Préstamo mutable
let r = &x; Crear referencia inmutable
let r = &mut x; Crear referencia mutable
'a Anotación de tiempo de vida (genérico)
fn longest<'a>(a: &'a str, b: &'a str) -> &'a str Función con parámetros de tiempo de vida
struct User {
name: String,
age: u32,
} Definición de struct
let u = User { name: String::from("A"), age: 30 }; Instanciación de struct
impl User {
fn new(name: &str) -> Self { ... }
} Bloque de implementación de métodos
struct Point(f64, f64); Struct tupla
enum Color {
Red,
Green,
Blue,
Rgb(u8, u8, u8),
} Enum con variantes (algunas con datos)
enum Option<T> { Some(T), None } Tipo Option (valor anulable)
enum Result<T, E> { Ok(T), Err(E) } Tipo Result (éxito o error)
match value {
Pattern => expr,
_ => default,
} Coincidencia de patrones (debe ser exhaustiva)
if let Some(x) = optional { ... } Desestructurar patrón individual
#[derive(Debug, Clone, PartialEq)] Auto-derivar traits comunes
trait Summary {
fn summarize(&self) -> String;
} Definición de trait
impl Summary for Article {
fn summarize(&self) -> String { ... }
} Implementar trait para un tipo
fn notify(item: &impl Summary) Restricción de trait (sintaxis impl)
fn notify<T: Summary + Display>(item: &T) Múltiples restricciones de trait
fn returns() -> impl Summary Tipo de retorno que implementa trait
dyn Trait Despacho dinámico (objeto trait)
Box<dyn Trait> Objeto trait alojado en el heap
let f = File::open("f.txt")?; Propagar error con operador ?
unwrap() Panic en Err/None (solo usar en tests)
expect("msg") Panic con mensaje personalizado en Err/None
unwrap_or(default) Devolver valor por defecto en Err/None
unwrap_or_else(|| compute()) Devolver valor calculado en Err/None
match result {
Ok(val) => ...,
Err(e) => ...,
} Manejar Result con match
map_err(|e| MyError::from(e)) Transformar tipo de error
panic!("critical error") Error irrecuperable (abortar)
let v: Vec<i32> = Vec::new(); Crear vector vacío
let v = vec![1, 2, 3]; Crear vector con valores (macro)
v.push(4); Añadir elemento al vector
v.pop(); Eliminar y devolver último elemento
v.iter().map(|x| x * 2).collect::<Vec<_>>() Transformar con cadena de iteradores
v.iter().filter(|x| **x > 2).collect::<Vec<_>>() Filtrar con iterador
let mut map = HashMap::new();
map.insert("key", value); Crear y poblar HashMap
map.get("key") Obtener valor de HashMap (devuelve Option)
map.entry("key").or_insert(0); Insertar si la clave no existe
let set: HashSet<i32> = HashSet::new(); Crear HashSet (valores únicos)
use std::thread;
thread::spawn(|| { ... }); Crear un nuevo hilo
handle.join().unwrap(); Esperar a que termine el hilo
Arc::new(Mutex::new(data)) Estado mutable compartido seguro entre hilos
use std::sync::mpsc;
let (tx, rx) = mpsc::channel(); Crear canal de paso de mensajes
tx.send(value).unwrap();
let received = rx.recv().unwrap(); Enviar y recibir a través del canal
async fn fetch() -> Result<()> { ... } Función asíncrona
let result = fetch().await?; Esperar resultado asíncrono
Cheat Sheet de Rust — Ownership, Borrowing, Lifetimes, Traits y Result/Option
Rust llegó a la 1.0 en 2015 y conserva el mismo modelo central desde entonces: ownership y borrowing comprobados en compilación, sin recolector de basura, sin null. La chuleta de abajo cubre más de 60 fragmentos entre básicos, ownership, structs y enums, traits, manejo de errores, colecciones y concurrencia. La mayoría de los líos en código Rust real no vienen de olvidar la sintaxis. Vienen de rarezas que parecen normales pero muerden. Pasar un `String` a una función por valor lo mueve, y el binding original deja de compilar a partir de esa línea. Un `Box<dyn Trait>` y un genérico `T: Trait` se parecen en el sitio de llamada pero cuestan distinto: uno es asignación en heap con dispatch dinámico, el otro se monomorfiza en compilación. El operador `?` solo funciona cuando el tipo de retorno absorbe el error mediante una conversión `From`. Estos son los fragmentos que se acaban consultando al depurar precisamente eso: la forma de borrow correcta, la anotación de lifetime adecuada, la conversión de error apropiada, sin tener que releer la referencia de Rust desde la línea uno cada vez.
Trampas habituales en Rust
Hay un puñado de patrones que merecen estar en la primera pantalla de cualquier archivo de Rust. Conviene preferir `&str` antes que `&String` en parámetros cuando solo se lee texto: `&str` acepta tanto literales como slices de un `String` ya en memoria, mientras que `&String` solo acepta lo segundo. Recurrir a `clone()` para desbloquear al borrow checker está bien como medida temporal, pero cada `.clone()` merece revisión, porque los clones baratos sobre `Vec` o `String` son asignaciones reales. El operador `?` se apoya en las conversiones `From`, así que definir `impl From<IoError> for MyError` permite a una función que devuelve `Result<T, MyError>` usar `?` sobre llamadas que devuelven `Result<T, IoError>` sin `map_err` a mano. Las funciones async devuelven un future que no hace nada hasta que se le hace await; llamar a `fetch()` sin `.await` no inicia ningún trabajo. Los trait objects necesitan un wrapper de `Box`, `&dyn` o `Arc` porque `dyn Trait` no tiene tamaño conocido. La chuleta agrupa esto en Básicos, Ownership, Structs y Enums, Traits, Manejo de errores, Colecciones y Concurrencia para que la sección adecuada esté a un clic.
- Más de 60 fragmentos prácticos de Rust
- 7 categorías desde básicos hasta concurrencia
- Propiedad y préstamos explicados
- Patrones de manejo de errores (Result, Option)
- Copia al portapapeles con un clic
- Sistema de traits y genéricos cubiertos
Gratis. Sin registro. Tus datos permanecen en tu navegador. Anuncios mediante Google AdSense (con consentimiento).
Por Marco B. ·