Alternativ/Benutzerdefinierte Schlüsseltypen

RustRustBeginner
Jetzt üben

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

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab untersuchen wir die Verwendung alternativer/benutzerdefinierter Schlüsseltypen in Rusts HashMap, die Typen umfassen können, die die Eq- und Hash-Traits implementieren, wie bool, int, uint, String und &str. Darüber hinaus können wir diese Traits für benutzerdefinierte Typen mithilfe des #[derive(PartialEq, Eq, Hash)]-Attributs implementieren, was es ihnen ermöglicht, als Schlüssel in einer HashMap zu verwendet werden.

Hinweis: Wenn das Lab keinen Dateinamen angibt, können Sie einen beliebigen Dateinamen verwenden. Beispielsweise können Sie main.rs verwenden und es mit rustc main.rs &&./main kompilieren und ausführen.

Alternativer/benutzerdefinierter Schlüsseltypen

Jeder Typ, der die Eq- und Hash-Traits implementiert, kann ein Schlüssel in einer HashMap sein. Dies umfasst:

  • bool (wenngleich nicht sehr nützlich, da es nur zwei mögliche Schlüssel gibt)
  • int, uint und alle davon abgeleiteten Variationen
  • String und &str (Tipp: Sie können eine HashMap mit String als Schlüssel haben und .get() mit einem &str aufrufen)

Beachten Sie, dass f32 und f64 Hash nicht implementieren, wahrscheinlich weil Gleitkomma-Präzisionsfehler dazu führen würden, sie als Hashtabellenschlüssel zu verwenden, was zu schwerwiegenden Fehlern führen würde.

Alle Sammlungsklassen implementieren Eq und Hash, wenn auch der von ihnen enthaltene Typ Eq und Hash implementiert. Beispielsweise wird Vec<T> Hash implementieren, wenn T Hash implementiert.

Sie können Eq und Hash für einen benutzerdefinierten Typ mit nur einer Zeile leicht implementieren: #[derive(PartialEq, Eq, Hash)]

Der Compiler wird den Rest erledigen. Wenn Sie mehr Kontrolle über die Details möchten, können Sie Eq und/oder Hash selbst implementieren. In dieser Anleitung werden die Details der Implementierung von Hash nicht behandelt.

Um mit der Verwendung einer struct in einer HashMap zu experimentieren, versuchen wir, ein sehr einfaches Benutzeranmeldesystem zu implementieren:

use std::collections::HashMap;

// Eq erfordert, dass Sie PartialEq für den Typ ableiten.
#[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!("Versuche Anmeldung...");

    let logon = Account {
        username,
        password,
    };

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

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

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

    let account_info = AccountInfo {
        name: "John Everyman",
        email: "[email protected]",
    };

    accounts.insert(account, account_info);

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

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

Zusammenfassung

Herzlichen Glückwunsch! Sie haben das Lab zu Alternativen/Benutzerdefinierten Schlüsseltypen abgeschlossen. Sie können in LabEx weitere Labs absolvieren, um Ihre Fähigkeiten zu verbessern.