マップの entry メソッドとその利用例をいくつか紹介する。

基礎知識

マップ系の型 (HashMapBTreeMap) の entry メソッドは、エントリ編集系のよくある処理のためのヘルパメソッドである。これにより、その他の編集用メソッド (get, get_mut, insert, remove など) のみを使った場合と比べ、処理の効率化や、条件分岐の削減ができる場合がある。

メソッドとその周辺仕様

以下は HashMapentry メソッドの宣言。


pub fn entry(&mut self, key: K) -> Entry<'_, K, V>

引数と戻り値、およびその型について。

利用例

代表的な利用例。

利用例 1

キーが未登録なら、キーに対応する値を登録

以下、or_insert メソッドを活用。


use std::collections::HashMap;

fn main() {
    let mut map = HashMap::from([("A", false)]);
    map.entry("A").or_insert(true);
    map.entry("B").or_insert(true);
    assert_eq!(map["A"], false);
    assert_eq!(map["B"], true);
}

利用例 2

キーが登録済なら、キーに対応する値を更新

以下、and_modify メソッドを活用。


use std::collections::HashMap;

fn main() {
    let mut map = HashMap::from([("A", false)]);
    map.entry("A").and_modify(|x| *x = true);
    map.entry("B").and_modify(|x| *x = true);
    assert_eq!(map.get("A"), Some(&true));
    assert_eq!(map.get("B"), None);
}

利用例 3

キーに対応する値を設定後、値への参照を取得 (簡易版)

以下、and_modifyor_insert を連結 (VCopy トレイトが必要)。


use std::collections::HashMap;
use std::hash::Hash;

fn main() {
    let mut map = HashMap::from([("A", false)]);
    let v1 = *set_map_val(&mut map, "A", true);
    let v2 = *set_map_val(&mut map, "B", true);
    assert_eq!(v1, map["A"]);
    assert_eq!(v2, map["B"]);
}

fn set_map_val<K, V>(map: &mut HashMap<K, V>, k: K, v: V) -> &V
where
    K: Eq + Hash,
    V: Copy,
{
    map.entry(k).and_modify(|x| *x = v).or_insert(v)
}

利用例 4

キーに対応する値を設定後、値への参照を取得 (発展版)

以下、VacantOcupied を個別に対応 (VCopy トレイトは不要)。


use std::collections::HashMap;
use std::collections::hash_map::Entry::*;
use std::hash::Hash;

fn main() {
    let mut map = HashMap::from([("A", false)]);
    let v1 = *set_map_val(&mut map, "A", true);
    let v2 = *set_map_val(&mut map, "B", true);
    assert_eq!(v1, map["A"]);
    assert_eq!(v2, map["B"]);
}

fn set_map_val<K, V>(map: &mut HashMap<K, V>, k: K, v: V) -> &V
where
    K: Eq + Hash,
{
    match map.entry(k) {
        Vacant(x) => x.insert(v),
        Occupied(x) => {
            let vr = x.into_mut();
            *vr = v;
            vr
        },
    }
}