Closed pjebs closed 3 years ago
Essentially an atomic version of:
val, exists := map.Load(key)
if !exists {
val, _ = map.LoadOrStore(key, func())
}
... = val
CC @bcmills
We can't change the existing LoadOrStore
method but we could in principle add a new method.
@ianlancetaylor if I understand correctly the proposal is to add a special case where if value interface{}
is a func() interface{}
(say) then use it as a callback. Now that isn't backward compatible as-is, but if we added a new type type LoadFunc func() interface{}
and only looked for values of that named type then it would be.
To me, overloading this API by shoehorning a callback into the value interface{}
seems worse than adding a new method.
Either way, though, I think this has a sharp edge. The callback function cannot block any other Map
method, including concurrent LoadOrStores
(that would be antithetical to sync.Map
). (To put it another way, it is not possible to implement that code snippet which includes a user-provided callback atomically without introducing unacceptable blocking.) It follows that the callbacks may be called multiple times concurrently. I think users may find that surprising.
This seems like a clear duplicate of the recently declined #44159.
Duplicate of #44159.
The proposal states:
value
more intelligently.value
is of typeFuncLit
with a single return value, then if the key does not exist in the map, it callsvalue
and stores the return value.Depending on the ambit of Go1 compatibility promise, feel free to mark this as a Go2 proposal.
Alternatively, a new method can be added to
Map
that has this behaviour built-in.