本文へスキップ
BecomeCoder

Rustコース · 第8章 コレクションとエラー処理 · レッスン33

HashMap ― キーと値で引く

ブラウザで完結

導入

「名前から点数を引く」「単語の出現回数を数える」——キーで値を高速に引きたいときは 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 += 1or_insert は値への可変参照を返すので、* で中身にアクセスして書き換えます。

HashMapString のキーを insert すると、そのキーの所有権は HashMap へムーブします(String はヒープを持つ型なので)。ここでも所有権のルールが一貫して働いていることに注目してください。

試すには

単語リストをループして entry(word).or_insert(0) して *count += 1 すると、各単語の出現回数が数えられます。entry ... or_insert は「無ければ初期化」の超頻出イディオムなので、手に馴染ませておきましょう。

実際に動かしてみよう

下のエディタにRustを書いて「実行」を押すと、学習用シミュレータが println! の出力を表示します(本物のrustcではなく、教材の範囲を再現した軽量エンジンです)。struct・enum・match・トレイト・Vec/String/HashMap・Option/Result なども動きます。本文の例を書き換えて動かしてみましょう(所有権・借用チェッカーのコンパイルエラーは再現しないため、動きの確認用として使ってください)。

Rust — ブラウザ内で実行(学習用シミュレータ)

Rustの教材サブセットを動かす学習用シミュレータを読み込みます(本物のrustcではなく、動きを再現した軽量な自作エンジンです)。
スクロールして表示された時点でも自動で読み込まれます。