Aprende Rust de forma correcta con estos consejos

Rust

fn leer_archivo(nombre_archivo: &str) -> Result<String, std::io::Error> {
    let contenido = std::fs::read_to_string(nombre_archivo)?; // Propaga el error si la lectura falla
    Ok(contenido)
}

fn obtener_primer_caracter(texto: Option<&str>) -> Option<char> {
    let primer_caracter = texto?.chars().next()?; // Propaga None si texto es None o si no hay primer caracter
    Some(primer_caracter)
}

fn main() {
    match leer_archivo("mi_archivo.txt") {
        Ok(contenido) => println!("Contenido: {}", contenido),
        Err(error) => eprintln!("Error al leer: {}", error),
    }

    let texto1 = Some("Rust");
    let primer_char1 = obtener_primer_caracter(texto1);
    println!("Primer caracter de {:?}: {:?}", texto1, primer_char1); // Primer caracter de Some("Rust"): Some('R')

    let texto2 = None;
    let primer_char2 = obtener_primer_caracter(texto2);
    println!("Primer caracter de {:?}: {:?}", texto2, primer_char2); // Primer caracter de None: None
}

Rust

struct Usuario {
    nombre: String,
    edad: Option<u32>,
    email: Option<String>,
    activo: bool,
}

impl Usuario {
    fn builder(nombre: String) -> UsuarioBuilder {
        UsuarioBuilder::new(nombre)
    }
}

struct UsuarioBuilder {
    nombre: String,
    edad: Option<u32>,
    email: Option<String>,
    activo: bool,
}

impl UsuarioBuilder {
    fn new(nombre: String) -> Self {
        UsuarioBuilder { nombre, edad: None, email: None, activo: false }
    }

    fn edad(mut self, edad: u32) -> Self {
        self.edad = Some(edad);
        self
    }

    fn email(mut self, email: String) -> Self {
        self.email = Some(email);
        self
    }

    fn activo(mut self, activo: bool) -> Self {
        self.activo = activo;
        self
    }

    fn build(self) -> Usuario {
        Usuario {
            nombre: self.nombre,
            edad: self.edad,
            email: self.email,
            activo: self.activo,
        }
    }
}

fn main() {
    let usuario1 = Usuario::builder("Alice".to_string())
        .edad(30)
        .activo(true)
        .build();

    let usuario2 = Usuario::builder("Bob".to_string())
        .email("bob@example.com".to_string())
        .build();

    println!("Usuario 1: {:?}", usuario1);
    println!("Usuario 2: {:?}", usuario2);
}

Rust

use std::ops::{Deref, DerefMut};

struct SmartString(String);

impl Deref for SmartString {
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for SmartString {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl SmartString {
    fn anunciar(&self) {
        println!("Esta es una SmartString: {}", self.0);
    }
}

fn imprimir_longitud(s: &String) {
    println!("Longitud: {}", s.len());
}

fn main() {
    let mut smart_str = SmartString("Hola".to_string());
    smart_str.anunciar(); // Llama al método de SmartString

    imprimir_longitud(&smart_str); // &SmartString se coerce a &String gracias a Deref

    *smart_str += " Mundo!"; // Mutación directa de la String interna gracias a DerefMut
    println!("{}", smart_str);
}

Rust

struct MiLista<T> {
    elementos: Vec<T>,
}

impl<T> MiLista<T> {
    fn new() -> Self {
        MiLista { elementos: Vec::new() }
    }

    fn agregar(&mut self, elemento: T) {
        self.elementos.push(elemento);
    }
}

impl<T> IntoIterator for MiLista<T> {
    type Item = T;
    type IntoIter = std::vec::IntoIter<Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        self.elementos.into_iter()
    }
}

impl<T> FromIterator<T> for MiLista<T> {
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
        MiLista { elementos: iter.into_iter().collect() }
    }
}

fn main() {
    let mut mi_lista = MiLista::new();
    mi_lista.agregar(1);
    mi_lista.agregar(2);
    mi_lista.agregar(3);

    for elemento in mi_lista {
        println!("Elemento: {}", elemento);
    }

    let otra_lista: MiLista<i32> = (0..5).collect();
    println!("Otra lista: {:?}", otra_lista.elementos);
}

Rust

#[cfg(target_os = "linux")]
fn plataforma_especifica() {
    println!("Ejecutando en Linux");
}

#[cfg(target_os = "windows")]
fn plataforma_especifica() {
    println!("Ejecutando en Windows");
}

#[cfg(feature = "debug_logs")]
fn imprimir_debug(mensaje: &str) {
    println!("DEBUG: {}", mensaje);
}

#[cfg(not(feature = "debug_logs"))]
fn imprimir_debug(_: &str) {} // No hacer nada si la característica "debug_logs" no está habilitada

fn main() {
    plataforma_especifica();
    imprimir_debug("Esto es un mensaje de depuración");
}

Rust

#[inline]
fn operacion_critica(a: i32, b: i32) -> i32 {
    a + b
}

#[cold]
fn manejar_error(error_codigo: i32) {
    eprintln!("Error con código: {}", error_codigo);
    // ... lógica de manejo de errores ...
}

fn main() {
    let resultado = operacion_critica(5, 3);
    println!("Resultado: {}", resultado);

    if resultado < 0 {
        manejar_error(-1);
    }
}

Rust

const PI: f64 = 3.14159;
static NOMBRE_APLICACION: &str = "Mi Aplicación Rust";
static mut CONTADOR: u32 = 0; // Requiere unsafe para modificar

fn main() {
    println!("Valor de PI: {}", PI);
    println!("Nombre de la aplicación: {}", NOMBRE_APLICACION);

    unsafe {
        CONTADOR += 1;
        println!("Contador: {}", CONTADOR);
    }
}

Checa este video donde prodras ver un poco de RUST

Conclusión

Rust, con su sofisticado sistema de tipos y su enfoque en el rendimiento, ofrece muchas herramientas poderosas que van más allá de lo básico. Explorar estas características y patrones menos comunes puede llevar tu código Rust a un nivel superior de eficiencia, seguridad y profesionalismo. ¡Anímate a sumergirte más profundo en el fascinante mundo de Rust!

Scroll al inicio