You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中如何基于SlotMap生成带默认值的SecondaryMap

结论

当前slotmap官方库(最新1.0.x稳定版)并未提供原生的、可直接从SlotMap生成填充好默认值的SecondaryMap的内置方法。

现有实现优化

你自己写的基础实现逻辑是正确的,但仅支持实现了Copy trait的值类型,且不支持闭包生成值,可调整为更通用的版本:

use slotmap::{SlotMap, SecondaryMap, Key};

// 支持传入闭包生成每个值的通用版本
fn create_secondary_map<K: Key, I, V, F: FnMut() -> V>(slotmap: &SlotMap<K, I>, mut f: F) -> SecondaryMap<K, V> {
    // 预分配空间避免扩容开销,性能优于直接new()
    let mut map = SecondaryMap::with_capacity(slotmap.capacity());
    slotmap.keys().for_each(|k| { map.insert(k, f()); });
    map
}

// 传入固定默认值的重载版本
fn create_secondary_map_with_default<K: Key, I, V: Clone>(slotmap: &SlotMap<K, I>, val: V) -> SecondaryMap<K, V> {
    create_secondary_map(slotmap, || val.clone())
}
实现你期望的链式调用

如果要达到slotmap.create_secondary(def_value)的调用形式,可以通过为SlotMap实现扩展trait来完成:

use slotmap::{SlotMap, SecondaryMap, Key};

pub trait SlotMapSecondaryExt<K: Key, I> {
    /// 用固定默认值创建SecondaryMap
    fn create_secondary<V: Clone>(&self, val: V) -> SecondaryMap<K, V>;
    /// 用无参闭包生成的值创建SecondaryMap
    fn create_secondary_with<V, F: FnMut() -> V>(&self, f: F) -> SecondaryMap<K, V>;
    /// 可选扩展:支持用键和原SlotMap中的值生成新值
    fn create_secondary_with_entry<V, F: FnMut(K, &I) -> V>(&self, f: F) -> SecondaryMap<K, V>;
}

impl<K: Key, I> SlotMapSecondaryExt<K, I> for SlotMap<K, I> {
    fn create_secondary<V: Clone>(&self, val: V) -> SecondaryMap<K, V> {
        self.create_secondary_with(|| val.clone())
    }

    fn create_secondary_with<V, F: FnMut() -> V>(&self, mut f: F) -> SecondaryMap<K, V> {
        let mut map = SecondaryMap::with_capacity(self.capacity());
        self.keys().for_each(|k| { map.insert(k, f()); });
        map
    }

    fn create_secondary_with_entry<V, F: FnMut(K, &I) -> V>(&self, mut f: F) -> SecondaryMap<K, V> {
        let mut map = SecondaryMap::with_capacity(self.capacity());
        self.iter().for_each(|(k, v)| { map.insert(k, f(k, v)); });
        map
    }
}
用法示例

引入上面的扩展trait后,就可以直接按你期望的方式调用:

// 用固定默认值
let secondary = slotmap.create_secondary(def_value);
// 用闭包生成独立的默认值
let secondary = slotmap.create_secondary_with(|| Default::default());
// 用原SlotMap的条目生成值
let secondary = slotmap.create_secondary_with_entry(|k, v| v.some_field.clone());

内容的提问来源于stack exchange,提问作者nir shahar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 23:54:01