在将结构插入地图而不重复它时,如何使用struct的成员作为自己的键?

ide*_*n42 5 rust borrow-checker

是否可以在映射中插入一个结构,其中键由插入的值所拥有?

在C中使用哈希映射时,这是我以前做过的事情.

伪代码示例:

struct MyStruct {
    pub map: BTreeMap<&String, StructThatContainsString>,
    // XXX            ^ Rust wants lifetime specified here!
}

struct StructThatContainsString {
    id: String,
    other_data: u32,
}

fn my_fn() {
    let ms = MyStruct { map: BTreeMap::new() };

    let item = StructThatContainsString {
        id: "Some Key".to_string(),
        other_data: 0,
    }

    ms.insert(&item.id, item);
}
Run Code Online (Sandbox Code Playgroud)

如何正确处理这种情况?


  • 如果这是不可能的,可以反过来做,其中值持有对密钥的引用,这将是一个String

  • 另一种方法是使用a set而不是a map,然后将整个存储struct为键,但在比较时只使用其中一个值(似乎它可以工作,但如果你想比较struct其他上下文,可能会适得其反).

Chr*_*son 7

它不适用于普通引用:

let item = StructThatContainsString {
    id: "Some Key".to_string(),
    other_data: 0,
}

ms.insert(&item.id, item);
Run Code Online (Sandbox Code Playgroud)

item移动到地图中,因此不能有任何待处理的借用/引用.

此外,类似的方法get_mut()会变得危险或不可能,因为它可以让您修改具有出色参考的项目.

假设想要这样做的原因是为了节省空间,显而易见的选择是:

  • 从值struct中取出密钥.如果您同时需要它,您可以在查找映射中的键时获取它,或者迭代器包含键和值.

  • 使用类似Rc值的关键部分. Rc<T>实现Ord(必需BTreeMap)if if T.