Tipos de claves alternativas/personalizadas

RustRustBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, exploramos el uso de tipos de claves alternativas/personalizadas en el HashMap de Rust, que pueden incluir tipos que implementen los tratos Eq y Hash, como bool, int, uint, String y &str. Además, podemos implementar estos tratos para tipos personalizados mediante el atributo #[derive(PartialEq, Eq, Hash)], lo que les permite ser utilizados como claves en un HashMap.

Nota: Si el laboratorio no especifica un nombre de archivo, puede utilizar cualquier nombre de archivo que desee. Por ejemplo, puede utilizar main.rs, compilar y ejecutarlo con rustc main.rs &&./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/BasicConceptsGroup -.-> rust/mutable_variables("Mutable Variables") rust/DataTypesGroup -.-> rust/string_type("String Type") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99261{{"Tipos de claves alternativas/personalizadas"}} rust/mutable_variables -.-> lab-99261{{"Tipos de claves alternativas/personalizadas"}} rust/string_type -.-> lab-99261{{"Tipos de claves alternativas/personalizadas"}} rust/function_syntax -.-> lab-99261{{"Tipos de claves alternativas/personalizadas"}} rust/expressions_statements -.-> lab-99261{{"Tipos de claves alternativas/personalizadas"}} rust/method_syntax -.-> lab-99261{{"Tipos de claves alternativas/personalizadas"}} rust/operator_overloading -.-> lab-99261{{"Tipos de claves alternativas/personalizadas"}} end

Tipos de claves alternativas/personalizadas

Cualquier tipo que implemente los tratos Eq y Hash puede ser una clave en HashMap. Esto incluye:

  • bool (aunque no es muy útil ya que solo hay dos claves posibles)
  • int, uint y todas sus variaciones
  • String y &str (consejo: puede tener un HashMap con claves de tipo String y llamar a .get() con un &str)

Tenga en cuenta que f32 y f64 no implementan Hash, probablemente porque los errores de precisión de punto flotante harían que utilizar los mismos como claves de hashmap fuera terriblemente propenso a errores.

Todas las clases de colección implementan Eq y Hash si su tipo contenido también implementa respectivamente Eq y Hash. Por ejemplo, Vec<T> implementará Hash si T implementa Hash.

Puede implementar fácilmente Eq y Hash para un tipo personalizado con solo una línea: #[derive(PartialEq, Eq, Hash)]

El compilador se encargará del resto. Si desea tener más control sobre los detalles, puede implementar Eq y/o Hash usted mismo. Esta guía no cubrirá los detalles de la implementación de Hash.

Para experimentar con el uso de una struct en HashMap, intentemos crear un sistema de inicio de sesión de usuario muy simple:

use std::collections::HashMap;

// Eq requiere que derive PartialEq en el tipo.
#[derive(PartialEq, Eq, Hash)]
struct Account<'a>{
    username: &'a str,
    password: &'a str,
}

struct AccountInfo<'a>{
    name: &'a str,
    email: &'a str,
}

type Accounts<'a> = HashMap<Account<'a>, AccountInfo<'a>>;

fn try_logon<'a>(accounts: &Accounts<'a>,
        username: &'a str, password: &'a str){
    println!("Username: {}", username);
    println!("Password: {}", password);
    println!("Attempting logon...");

    let logon = Account {
        username,
        password,
    };

    match accounts.get(&logon) {
        Some(account_info) => {
            println!("Successful logon!");
            println!("Name: {}", account_info.name);
            println!("Email: {}", account_info.email);
        },
        _ => println!("Login failed!"),
    }
}

fn main(){
    let mut accounts: Accounts = HashMap::new();

    let account = Account {
        username: "j.everyman",
        password: "password123",
    };

    let account_info = AccountInfo {
        name: "John Everyman",
        email: "j.everyman@email.com",
    };

    accounts.insert(account, account_info);

    try_logon(&accounts, "j.everyman", "psasword123");

    try_logon(&accounts, "j.everyman", "password123");
}

Resumen

¡Felicidades! Has completado el laboratorio de Tipos de Claves Alternativas/Personalizadas. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.