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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- HashMapを構築する
- Entry APIとデフォルト値
- HashSetを扱う
- カウントとグループ化