-
Notifications
You must be signed in to change notification settings - Fork 6
Description
I have a use case where it would be convenient to insert the default value on a call to get()
or on immutable index. For example, suppose you want to store RefCell
s in a DefaultHashMap
. You would presumably use the immutable access methods for the same reason you are using a RefCell
. But then any interior mutation of the RefCell
actually mutates self.default
.
You can't just insert the default value in get()
, because get()
borrows self
immutably. You also can't just put the backing HashMap
in a RefCell
, either, because RefCell
returns a RefMut
that wouldn't outlive the call to get()
, and thus the lifetime of the reference extracted from the RefMut
can't outlive the call to get()
and so can't be returned.
The way to do achieve this is to put the backing HashMap
in a RefCell
and then use Ref::map()
, which gives a Ref
object that can be returned:
pub fn get(&self, k: K) -> Ref<'_, V> {
Ref::map(self.hash_map.borrow(), |hm| hm.get(k))
}
or something like that.
The user needs to choose the consequences of insert on read, or else they could end up accidentally trying to allocate the universe. Thus I propose the semantics be selectible, defaulting to insert on write. You'd have an enum:
// In the `default` module:
enum InsertSemantics {
OnWrite,
OnRead
}
// In the client code:
let mut map = defaultmap::HashMap::with_semantics(InsertSemantics::OnRead);
...
// Might as well make it settable:
map.set_semantics(InsertSemantics::OnWrite);
This is obviously a breaking change.
What do you think?