Zero-value Mutexes are Valid

The zero-value of sync.Mutex and sync.RWMutex is valid, so you almostnever need a pointer to a mutex.

BadGood
  1. mu := new(sync.Mutex)
  2. mu.Lock()
  1. var mu sync.Mutex
  2. mu.Lock()

If you use a struct by pointer, then the mutex can be a non-pointer field.

Unexported structs that use a mutex to protect fields of the struct may embedthe mutex.

  1. type smap struct {
  2. sync.Mutex // only for unexported types
  3.  
  4. data map[string]string
  5. }
  6.  
  7. func newSMap() smap {
  8. return &smap{
  9. data: make(map[string]string),
  10. }
  11. }
  12. func (m smap) Get(k string) string {
  13. m.Lock()
  14. defer m.Unlock()
  15.  
  16. return m.data[k]
  17. }
  1. type SMap struct {
  2. mu sync.Mutex
  3.  
  4. data map[string]string
  5. }
  6.  
  7. func NewSMap() SMap {
  8. return &SMap{
  9. data: make(map[string]string),
  10. }
  11. }
  12. func (m SMap) Get(k string) string {
  13. m.mu.Lock()
  14. defer m.mu.Unlock()
  15.  
  16. return m.data[k]
  17. }
Embed for private types or types that need to implement the Mutex interface.For exported types, use a private field.