How to use a struct’s member as its own key when inserting the struct into a map without duplicating it?

It’s not going to work with plain references:

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

ms.insert(&item.id, item);

item is moved into the map, so there can’t be any pending borrows/references.

Also, methods like get_mut() would become dangerous or impossible, as it would let you modify the item that has an outstanding reference.

Assuming the reason for wanting to do this is to save space, the obvious options are:

  • Take the key out of the value struct. If you need it at the same time, you’ve either got it when looking up a key in the map, or the iterators include both key and value:

    struct OnlyKey {
        id: String,
    }
    
    struct OnlyValue {
        other_data: u32,
    }
    

    This can be cleaned up with appropriate methods to split apart / recombine the various pieces.

  • Use something like Rc for the key part of the value. Rc<T> implements Ord (required for BTreeMap) if T does.

    struct StructThatContainsString {
        id: Rc<String>,
        other_data: u32,
    }
    

Leave a Comment