17.7.1 Alternate/custom key types

EqHash trait을 구현하는 모든 타입은 HashMap의 키가 될 수 있다. 다음을 포함:

  • bool (가능한 키가 두 개 뿐이라 유용하진 않음)
  • int, uint, 과 이들의 모든 변수형
  • String&str (protip: String을 키로 갖는 HashMap을 만들 수 있고 &str.get()을 호출할 수 있다.)

f32f64Hash를 구현하지 않는다, floating-point 정밀도 에러로 인해 에러가 발생하는 경향이 있기 때문이다.

모든 콜렉션 클래스들은 그들이 보관하는 타입들이 각기 EqHash를 구현했다면 EqHash를 구현한다. 예를 들어, Vec<T>THash를 구현했다면 Hash를 구현하게 될 것이다.

사용자 정의 타입에 단 한줄로 EqHash를 쉽게 구현할 수 있다: #[derive(PartialEq, Eq, Hash)]

컴파일러가 나머지 작업을 수행하게 될 것이다. 보다 세밀하게 제어하고 싶다면, Eq와/나 Hash를 스스로 구현하면 된다. 이 가이드에서는 Hash 구현의 세부 사항을 다루지 않는다.

HashMap에서 구조체를 사용하는, 아주 간단한 사용자 로그온 시스템을 만들어보자.

use std::collections::HashMap;

// Eq는 PartialEq의 파생을 요구한다.
#[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: username,
        password: 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: "[email protected]",
    };

    accounts.insert(account, account_info);

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

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

results matching ""

    No results matching ""