導入
「名前から点数を引く」「単語の出現回数を数える」——キーで値を高速に引きたいときは HashMap<K, V> です。他言語の辞書・連想配列・Map にあたります。
説明
use std::collections::HashMap; // 標準ライブラリから取り込む
fn main() {
let mut scores: HashMap<String, i32> = HashMap::new();
scores.insert(String::from("Alice"), 90);
scores.insert(String::from("Bob"), 80);
// 取り出し(get は Option を返す:キーが無いかもしれないから)
match scores.get("Alice") {
Some(v) => println!("Alice: {v}"),
None => println!("見つからない"),
}
// キーが無ければ挿入、あれば既存を使う(カウントの定番)
let count = scores.entry(String::from("Carol")).or_insert(0);
*count += 1; // 参照なので * で中身を書き換える
// 全件をたどる
for (name, score) in &scores {
println!("{name} => {score}");
}
}
use std::collections::HashMap;… 使う前に取り込みが必要です。insert(キー, 値)で追加・上書き。get(キー)は「キーが無いかもしれない」のでOptionを返します(第7章の考え方が一貫)。entry(キー).or_insert(既定)… 「あれば取得、無ければ挿入」を1行で。出現回数のカウントなどで頻出のパターンです。*count += 1…or_insertは値への可変参照を返すので、*で中身にアクセスして書き換えます。
HashMap に String のキーを insert すると、そのキーの所有権は HashMap へムーブします(String はヒープを持つ型なので)。ここでも所有権のルールが一貫して働いていることに注目してください。
試すには
単語リストをループして entry(word).or_insert(0) して *count += 1 すると、各単語の出現回数が数えられます。entry ... or_insert は「無ければ初期化」の超頻出イディオムなので、手に馴染ませておきましょう。