本文簡要介紹rust語言中 Struct std::collections::HashMap
的用法。
用法
pub struct HashMap<K, V, S = RandomState> { /* fields omitted */ }
通過二次探測和 SIMD 查找實現的hash map。
默認情況下,HashMap
使用選定的哈希算法來抵禦 HashDoS 攻擊。該算法是隨機播種的,並且會盡合理的最大努力從主機提供的高質量、安全的隨機源生成此種子,而不會阻塞程序。因此,種子的隨機性取決於係統隨機數生成器在創建種子時的輸出質量。特別是,當係統的熵池異常低時(例如在係統引導期間)生成的種子的質量可能較低。
目前默認的哈希算法是 SipHash 1-3,盡管將來可能會隨時更改。雖然它的性能對於中等大小的 key 非常有競爭力,但對於整數等小 key 以及長字符串等大 key ,其他哈希算法的性能將優於它,盡管這些算法通常無法防禦 HashDoS 等攻擊。
可以使用 default
、 with_hasher
和 with_capacity_and_hasher
方法在每個 HashMap
的基礎上替換哈希算法。有很多替代方案 hashing algorithms available on crates.io 。
要求鍵實現 Eq
和 Hash
特征,盡管這通常可以通過使用 #[derive(PartialEq, Eq, Hash)]
來實現。如果您自己實現這些,重要的是要滿足以下屬性:
k1 == k2 -> hash(k1) == hash(k2)
換句話說,如果兩個鍵相等,則它們的哈希值必須相等。
以這樣一種方式修改鍵是一個邏輯錯誤,即鍵的哈希(由 Hash
特征確定)或其相等性(由 Eq
特征確定)在映射中發生更改。這通常隻能通過 Cell
、 RefCell
、全局狀態、I/O 或不安全代碼實現。未指定由此類邏輯錯誤導致的行為,但不會導致未定義的行為。這可能包括Panics、不正確的結果、中止、內存泄漏和不終止。
哈希表實現是 Google SwissTable 的 Rust 端口。 SwissTable 的原始 C++ 版本可以在 這裏 中找到,並且 CppCon talk 概述了該算法的工作原理。
例子
use std::collections::HashMap;
// Type inference lets us omit an explicit type signature (which
// would be `HashMap<String, String>` in this example).
let mut book_reviews = HashMap::new();
// Review some books.
book_reviews.insert(
"Adventures of Huckleberry Finn".to_string(),
"My favorite book.".to_string(),
);
book_reviews.insert(
"Grimms' Fairy Tales".to_string(),
"Masterpiece.".to_string(),
);
book_reviews.insert(
"Pride and Prejudice".to_string(),
"Very enjoyable.".to_string(),
);
book_reviews.insert(
"The Adventures of Sherlock Holmes".to_string(),
"Eye lyked it alot.".to_string(),
);
// Check for a specific one.
// When collections store owned values (String), they can still be
// queried using references (&str).
if !book_reviews.contains_key("Les Misérables") {
println!("We've got {} reviews, but Les Misérables ain't one.",
book_reviews.len());
}
// oops, this review has a lot of spelling mistakes, let's delete it.
book_reviews.remove("The Adventures of Sherlock Holmes");
// Look up the values associated with some keys.
let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
for &book in &to_find {
match book_reviews.get(book) {
Some(review) => println!("{}: {}", book, review),
None => println!("{} is unreviewed.", book)
}
}
// Look up the value for a key (will panic if the key is not found).
println!("Review for Jane: {}", book_reviews["Pride and Prejudice"]);
// Iterate over everything.
for (book, review) in &book_reviews {
println!("{}: \"{}\"", book, review);
}
可以從數組初始化具有已知項目列表的HashMap
:
use std::collections::HashMap;
let solar_distance = HashMap::from([
("Mercury", 0.4),
("Venus", 0.7),
("Earth", 1.0),
("Mars", 1.5),
]);
HashMap
實現了 Entry API
,它允許使用複雜的方法來獲取、設置、更新和刪除鍵及其值:
use std::collections::HashMap;
// type inference lets us omit an explicit type signature (which
// would be `HashMap<&str, u8>` in this example).
let mut player_stats = HashMap::new();
fn random_stat_buff() -> u8 {
// could actually return some random value here - let's just return
// some fixed value for now
42
}
// insert a key only if it doesn't already exist
player_stats.entry("health").or_insert(100);
// insert a key using a function that provides a new value only if it
// doesn't already exist
player_stats.entry("defence").or_insert_with(random_stat_buff);
// update a key, guarding against the key possibly not being set
let stat = player_stats.entry("attack").or_insert(100);
*stat += random_stat_buff();
將 HashMap
與自定義鍵類型一起使用的最簡單方法是派生 Eq
和 Hash
。我們還必須派生 PartialEq
。
use std::collections::HashMap;
#[derive(Hash, Eq, PartialEq, Debug)]
struct Viking {
name: String,
country: String,
}
impl Viking {
/// Creates a new Viking.
fn new(name: &str, country: &str) -> Viking {
Viking { name: name.to_string(), country: country.to_string() }
}
}
// Use a HashMap to store the vikings' health points.
let vikings = HashMap::from([
(Viking::new("Einar", "Norway"), 25),
(Viking::new("Olaf", "Denmark"), 24),
(Viking::new("Harald", "Iceland"), 12),
]);
// Use derived implementation to print the status of the vikings.
for (viking, health) in &vikings {
println!("{:?} has {} hp", viking, health);
}
相關用法
- Rust HashMap.get用法及代碼示例
- Rust HashMap.try_insert用法及代碼示例
- Rust HashMap.keys用法及代碼示例
- Rust HashMap.iter用法及代碼示例
- Rust HashMap.iter_mut用法及代碼示例
- Rust HashMap.retain用法及代碼示例
- Rust HashMap.with_capacity_and_hasher用法及代碼示例
- Rust HashMap.clear用法及代碼示例
- Rust HashMap.reserve用法及代碼示例
- Rust HashMap.with_hasher用法及代碼示例
- Rust HashMap.into_keys用法及代碼示例
- Rust HashMap.into_values用法及代碼示例
- Rust HashMap.get_mut用法及代碼示例
- Rust HashMap.is_empty用法及代碼示例
- Rust HashMap.drain用法及代碼示例
- Rust HashMap.drain_filter用法及代碼示例
- Rust HashMap.len用法及代碼示例
- Rust HashMap.remove用法及代碼示例
- Rust HashMap.insert用法及代碼示例
- Rust HashMap.entry用法及代碼示例
- Rust HashMap.capacity用法及代碼示例
- Rust HashMap.contains_key用法及代碼示例
- Rust HashMap.values用法及代碼示例
- Rust HashMap.values_mut用法及代碼示例
- Rust HashMap用法及代碼示例
注:本文由純淨天空篩選整理自rust-lang.org大神的英文原創作品 Struct std::collections::HashMap。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。