• 更改或自定义关键字类型

    更改或自定义关键字类型

    任何实现了 EqHash trait 的类型都可以充当 HashMap 的键。这包括:

    • bool (当然这个用处不大,因为只有两个可能的键)
    • intunit,以及所有这类型的变量
    • String&str(友情提示:可以创建一个由 String 构成键的 HashMap,并以一个 &str 来调用 .get())(原文:String and &str (protip: you can have a HashMap keyed by String and call .get() with an &str))

    需要注意的是 f32f64 没有实现 Hash,很大程度上是由于浮点精度误差(floating-point precision error)会使浮点类型作为散列映射键发生严重的错误。

    对于所有的集合类(collection),如果它们包含的类型都分别实现 EqHash,那么这些集合类也都会实现 EqHash。例如,若 T 实现了 Hash,则 Vec<T> 也会实现 Hash

    对自定义类型可以轻松地实现 EqHash,只需加上一行代码: #[derive(PartialEq, Eq, Hash)]

    编译器将会完成余下的工作。如果你想控制更多的细节内容,你可以实现自己定制的 Eq 和/或 Hash。本指南不包含实现 Hash 的细节内容。

    为了玩玩怎么使用 HashMap 中的 struct,让我们试着做一个非常简易的登录系统:

    1. use std::collections::HashMap;
    2. // Eq 要求你对此类型派生了 PartiaEq。
    3. #[derive(PartialEq, Eq, Hash)]
    4. struct Account<'a>{
    5. username: &'a str,
    6. password: &'a str,
    7. }
    8. struct AccountInfo<'a>{
    9. name: &'a str,
    10. email: &'a str,
    11. }
    12. type Accounts<'a> = HashMap<Account<'a>, AccountInfo<'a>>;
    13. fn try_logon<'a>(accounts: &Accounts<'a>,
    14. username: &'a str, password: &'a str){
    15. println!("Username: {}", username);
    16. println!("Password: {}", password);
    17. println!("Attempting logon...");
    18. let logon = Account {
    19. username: username,
    20. password: password,
    21. };
    22. match accounts.get(&logon) {
    23. Some(account_info) => {
    24. println!("Successful logon!");
    25. println!("Name: {}", account_info.name);
    26. println!("Email: {}", account_info.email);
    27. },
    28. _ => println!("Login failed!"),
    29. }
    30. }
    31. fn main(){
    32. let mut accounts: Accounts = HashMap::new();
    33. let account = Account {
    34. username: "j.everyman",
    35. password: "password123",
    36. };
    37. let account_info = AccountInfo {
    38. name: "John Everyman",
    39. email: "j.everyman@email.com",
    40. };
    41. accounts.insert(account, account_info);
    42. try_logon(&accounts, "j.everyman", "psasword123");
    43. try_logon(&accounts, "j.everyman", "password123");
    44. }