use std::collections::HashMap;
fn call(number: &str) -> &str {
match number {
"798-1364" => "Абонент выключен или находится вне зоны действия сети.
Пожалуйста, позвоните позднее.",
"645-7689" => "Здравствуйте, это Mr. Awesome's Pizza. Меня зовут Фред.
Что я могу сделать для вас?",
_ => "Привет! Кто это опять?"
}
}
fn main() {
let mut contacts = HashMap::new();
contacts.insert("Даниель", "798-1364");
contacts.insert("Эшли", "645-7689");
contacts.insert("Кейти", "435-8291");
contacts.insert("Роберт", "956-1745");
// Возьмём ссылку и вернём `Option<&V>`
match contacts.get(&"Даниель") {
Some(&number) => println!("Звоним Даниелю: {}", call(number)),
_ => println!("У нас нет номера Даниеля."),
}
// `HashMap::insert()` вернёт `None`, если мы добавляем
// новое значение, иначе - `Some(value)`
contacts.insert("Даниель", "164-6743");
match contacts.get(&"Эшли") {
Some(&number) => println!("Звоним Эшли: {}", call(number)),
_ => println!("У нас нет номера Эшли."),
}
contacts.remove(&"Эшли");
// `HashMap::iter()` возвращает итератор, который в произвольном
// порядке отдаёт пары `(&'a key, &'a value)`.
for (contact, &number) in contacts.iter() {
println!("Звоним {}: {}", contact, call(number));
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Для большей информации о том, как работает хеширование и хэш-карты (который иногда называются хэш-таблицами), вы можете обратиться к Wikipedia.
Любой тип, реализующий типажи Eq и Hash могут являться ключами в HashMap. Туда входят:
• bool (хотя он будет не очень полезен, так как будет всего лишь два возможных ключа)
• int, uint и все их варианты
• String и &str (подсказка: вы можете сделать HashMap с ключами типа String, а вызывать .get() - с &str)
Заметьте, что f32 и f64 не реализуют Hash, из-за того, что ошибки точности при работе с плавающей запятой могут привести к ужасным ошибкам при использовании их в качестве ключей для хэш-карт.
Все классы коллекций реализуют Eq и Hash если содержащийся в них тип также реализует Eq и Hash. Например, Vec<T> реализует Hash, если T реализует Hash.
Вы можете легко реализовать Eq и Hash для пользовательских типов добавив всего лишь одну строчку: #[derive(PartialEq, Eq, Hash)]
Компилятор сделает всё остальное. Если вы хотите больше контроля над деталями, вы можете сами реализовать Eq и/или Hash. Данное руководство не охватывает специфику реализации Hash.
Чтобы поиграть с использованием struct в 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,
emaiclass="underline" &'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);
println!("Пароль: {}", password);
println!("Попытка входа...");
let logon = Account {
username,
password,
};
match accounts.get(&logon) {
Some(account_info) => {
println!("Успешный вход!");
println!("Имя: {}", account_info.name);
println!("Emaiclass="underline" {}", account_info.email);
},
_ => println!("Ошибка входа!"),
}
}
fn main(){
let mut accounts: Accounts = HashMap::new();
let account = Account {
username: "j.everyman",
password: "password123",
};
let account_info = AccountInfo {
name: "John Everyman",
emaiclass="underline" "j.everyman@email.com",
};