Zero values for sync.Mutex
and sync.RWMutex
are effective. So, pointers to mutexes are basically unnecessary.
Not recommended:
mu := new(sync.Mutex)
mu.Lock()
Recommended:
var mu sync.Mutex
mu.Lock()
If you use a pointer to a structure, the mutex should be a non-pointer field of the structure. Even if the structure is not exported, do not embed the mutex directly into the structure.
Not recommended:
type SMap struct {
sync.Mutex
data map[string]string
}
func NewSMap() *SMap {
return &SMap{
data: make(map[string]string),
}
}
func (m *SMap) Get(k string) string {
m.Lock()
defer m.Unlock()
return m.data[k]
}
// The Mutex field, Lock, and Unlock methods are a part of the SMap exported API without explicit declaration.
Recommended:
type SMap struct {
mu sync.Mutex
data map[string]string
}
func NewSMap() *SMap {
return &SMap{
data: make(map[string]string),
}
}
func (m *SMap) Get(k string) string {
m.mu.Lock()
defer m.mu.Unlock()
return m.data[k]
}
// The mutex and its methods are implementation details of SMap and are not visible to its callers.