Estructuras básicas, narrativa y opciones de Rust

Clase 18 de 20Curso de Rust básico

Resumen

Las aplicaciones que desarrolles en Rust comenzarán a tener necesidades avanzadas y vas a requerir más herramientas para resolver diversos escenarios. Veamos varias utilidades de Rust para resolver problemas comunes a la hora de programar.

Valores por defecto en los errores

Para evitar que tu aplicación se detenga por un error y que continúe ejecutándose, puedes colocar un valor por defecto utilizando unwrap_or().

fn main() {
    println!("Ingrese su edad: ");
    let mut edad: String = String::new();
    std::io::stdin().read_line(&mut edad).unwrap();
    let edad_int: u8 = edad.trim().parse().unwrap_or(18);

    println!("Tienes {} años: ", edad_int);	
}

Si el usuario ingresa una letra en lugar de un número cuando se le solicita su edad, la conversión del tipo de dato fallará, pero el unwrap_or() devolverá un valor establecido por defecto y tu aplicación continuará operando.

Estructuras de datos

Crear estructuras de datos para almacenar, dentro de una misma variable, atributos pertenecientes a una misma cosa. Puedes crear estructuras que tendrán la forma de tus datos de la siguiente manera:

struct Person {
    nombre: String,
    apellido: String,
    edad: i32,
    pais: String,
}

fn main() {
    let persona = Person {
        nombre: "Kevin".to_string(),
        apellido: "Fiorentino".to_string(),
        edad: 27,
        pais: "Argentina".to_string(),
    };

    println!("{}", persona.nombre);
    println!("{}", persona.apellido);
    println!("{}", persona.edad);
    println!("{}", persona.pais);
}

Con la palabra clave struct, declaras las propiedades de tu estructura y puedes crear una variable que almacene estos datos y acceder a ellos mediante un punto “.”.

NOTA: Las estructuras utilizan CamelCase para nombrar a las mismas a diferencia de las variables o funciones que utilizan snack_case.

 

Implementaciones de estructuras

Una estructura puede extenderse e implementar funciones para realizar determinada lógica, como crear un nuevo objeto de ese tipo y realizar algún cálculo.

struct Person {
    nombre: String,
    apellido: String,
    edad: i32,
    pais: String,
}

impl Person {
    fn new_person(nombre: String, apellido: String, edad: i32, pais: String) -> Person {
        return Person { nombre, apellido, edad, pais };
    }
}

fn main() {
    let persona: Person = Person::new_person("Kevin".to_string(), "Fiorentino".to_string(), 27, "Argentina".to_string());

    println!("{}", persona.nombre);
}

Utilizando la palabra reservada impl, la función new_person creará un objeto Person pasándole como parámetro los datos que necesita y devolviendo el mismo para su posterior utilización. Has el llamado a estas funciones implementadas en una estructura con Person::XXXXX.

Almacenamiento clave/valor

Otra manera de almacenar información, además de las estructuras y los vectores, son los denominados HashMap. Los mismos son “diccionarios” de datos, del tipo clave/valor, donde para acceder a un elemento, en lugar de utilizar el índice del mismo como en un vector, se utiliza la Clave, que puede ser un string o un número, para colocarle un nombre al Valor y obtenerlo.

use std::collections::{HashMap};

fn main() {
    let mut diccionario: HashMap<&str, &str> = HashMap::new();

    diccionario.insert("Manzana", "La manzana es roja.");
    diccionario.insert("Banana", "La banana es amarilla.");
    diccionario.insert("Naranja", "La naranja es... naranja.");

    println!("{}", diccionario["Manzana"]);			// La manzana es roja.
}

De esta forma, puedes guardar un nuevo valor con insert() y acceder al mismo a través de su clave.

Explora estas nuevas estructuras y tipos de datos para resolver diversas situaciones donde se vuelve algo más complicado manipular la información y mantener la claridad y prolijidad en tu código.


Contribución creada por: Kevin Fiorentino.