diff --git a/src/sync/map.go b/src/sync/map.go index 5eeff9d3..f27450ce 100644 --- a/src/sync/map.go +++ b/src/sync/map.go @@ -34,6 +34,17 @@ func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bo return value, false } +func (m *Map) LoadAndDelete(key interface{}) (value interface{}, loaded bool) { + m.lock.Lock() + defer m.lock.Unlock() + value, ok := m.m[key] + if !ok { + return nil, false + } + delete(m.m, key) + return value, true +} + func (m *Map) Store(key, value interface{}) { m.lock.Lock() defer m.lock.Unlock() diff --git a/src/sync/map_test.go b/src/sync/map_test.go new file mode 100644 index 00000000..f493bdfb --- /dev/null +++ b/src/sync/map_test.go @@ -0,0 +1,19 @@ +package sync_test + +import ( + "sync" + "testing" +) + +func TestMapLoadAndDelete(t *testing.T) { + var sm sync.Map + sm.Store("present", "value") + + if v, ok := sm.LoadAndDelete("present"); !ok || v != "value" { + t.Errorf("LoadAndDelete returned %v, %v, want value, true", v, ok) + } + + if v, ok := sm.LoadAndDelete("absent"); ok || v != nil { + t.Errorf("LoadAndDelete returned %v, %v, want nil, false", v, ok) + } +}