0Pricing
Learn Rust Coding · レッスン

Entry APIとデフォルト値

効率的な方法で値を更新します。

「Entry APIとデフォルト値」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。

Entry APIを使う理由

キーが存在する場合は値を更新し、存在しない場合はデフォルト値を挿入したいことがよくあります。

getとinsertを組み合わせてもできますが、扱いにくくなります。entry APIなら、これを1つの処理で簡潔に行えます。

entryはスロットを返す

entry(key)を呼び出すと、マップ内のそのキーの場所へのハンドルが得られます。

そのハンドルを使って、デフォルト値を入れるか、すでに存在する値を変更するかを決められます。

use std::collections::HashMap;

fn main() {
    let mut m: HashMap<&str, i32> = HashMap::new();
    m.entry("a").or_insert(0);
    println!("{}", m["a"]);
}

or_insert

or_insert(default)は、キーが存在しない場合だけデフォルト値を挿入し、その値への可変参照を返します。

キーがすでに存在する場合、デフォルト値は無視され、既存の値が返されます。

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("a", 10);
    m.entry("a").or_insert(99);
    m.entry("b").or_insert(99);
    println!("a={}, b={}", m["a"], m["b"]);
}

参照を通じて値を変更する

or_insertは可変参照を返すため、値をすぐに変更できます。

*でデリファレンスして、その場で値を更新します。これがカウント処理の基本です。

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    let count = m.entry("hits").or_insert(0);
    *count += 1;
    *count += 1;
    println!("hits = {}", m["hits"]);
}

ループ内で数える

典型的なパターンは、各要素について格納場所を取得し、デフォルト値を0にしてからインクリメントする方法です。

これにより、要素ごとに1行のロジックで出現回数を集計できます。

use std::collections::HashMap;

fn main() {
    let mut counts = HashMap::new();
    for c in "hello".chars() {
        *counts.entry(c).or_insert(0) += 1;
    }
    println!("l appears {} times", counts[&'l']);
}

or_insert_with

デフォルト値の作成にコストがかかる場合は、or_insert_withを使います。キーが存在しない場合にだけ実行されるクロージャを受け取ります。

これにより、実際には必要にならない値を作成せずに済みます。

use std::collections::HashMap;

fn main() {
    let mut m: HashMap<&str, Vec<i32>> = HashMap::new();
    m.entry("nums").or_insert_with(Vec::new).push(1);
    m.entry("nums").or_insert_with(Vec::new).push(2);
    println!("{:?}", m["nums"]);
}

and_modify

and_modifyは、キーがすでに存在する場合にだけ、その値に対してクロージャを実行します。

or_insertと連結すると、存在する場合は変更し、存在しない場合は初期値を挿入するという両方のケースに対応できます。

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("x", 5);
    m.entry("x").and_modify(|v| *v += 10).or_insert(0);
    m.entry("y").and_modify(|v| *v += 10).or_insert(1);
    println!("x={}, y={}", m["x"], m["y"]);
}

or_default

値の型にDefaultが実装されている場合(整数の0や空のVecなど)、or_defaultがそのデフォルト値を使います。

or_insert(Default::default())の省略形です。

use std::collections::HashMap;

fn main() {
    let mut m: HashMap<&str, i32> = HashMap::new();
    *m.entry("score").or_default() += 7;
    println!("score = {}", m["score"]);
}

キーごとにリストを作る

Entry APIは、要素をベクタにグループ化するときに特に便利です。

各キーについて、最初は空のVecをデフォルト値として用意し、その後はそこにあるベクタへ要素を追加します。

use std::collections::HashMap;

fn main() {
    let mut groups: HashMap<bool, Vec<i32>> = HashMap::new();
    for n in [1, 2, 3, 4] {
        groups.entry(n % 2 == 0).or_default().push(n);
    }
    println!("evens: {:?}", groups[&true]);
}

getとinsertを別々に使わない理由

getしてからinsertする処理を別々に行うと、キーを2回検索することになり、借用チェッカーとの相性もよくありません。

Entry APIは1回だけ検索し、安全な参照を1つだけ正確に渡してくれるため、より高速で簡潔です。

組み合わせて使う

ここではカウント処理とデフォルト値を組み合わせ、各文字で始まる異なる単語が何個あるかを調べます。

1行で集計するパターンがどのように機能するかに注目してください。

use std::collections::HashMap;

fn main() {
    let words = ["ant", "art", "bee"];
    let mut by_first: HashMap<char, i32> = HashMap::new();
    for w in words {
        *by_first.entry(w.chars().next().unwrap()).or_insert(0) += 1;
    }
    println!("a: {}", by_first[&'a']);
}

理解度チェック

文字ごとに1回の検索で、文字を数えたいとします。

まとめ

entry APIを使うと、1回の検索で挿入または更新を行えます。

or_insert、or_insert_with、or_default、and_modifyを使って、要素のカウントやキーごとのリスト作成を簡潔に行いました。

よくある質問

「Entry APIとデフォルト値」レッスンは無料ですか?

はい。「Entry APIとデフォルト値」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。

「Entry APIとデフォルト値」で何を学びますか?

効率的な方法で値を更新します。 ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Learn Rust Codingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「Entry APIとデフォルト値」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLearn Rust Codingレッスンでコードを書いて実行できますか?

はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. HashMapを構築する
  2. Entry APIとデフォルト値
  3. HashSetを扱う
  4. カウントとグループ化
← Learn Rust Codingに戻る