同样,请注意用户对暴露内部状态的 map 或 slice 的修改。
Bad | Good |
---|---|
type Stats struct { mu sync.Mutex
counters map[string]int }
// Snapshot 返回当前状态。 func (s *Stats) Snapshot() map[string]int { s.mu.Lock() defer s.mu.Unlock()
return s.counters }
// snapshot 不再受互斥锁保护 // 因此对 snapshot 的任何访问都将受到数据竞争的影响 // 影响 stats.counters snapshot := stats.Snapshot() |
type Stats struct { mu sync.Mutex
counters map[string]int }
func (s *Stats) Snapshot() map[string]int { s.mu.Lock() defer s.mu.Unlock()
result := make(map[string]int, len(s.counters)) for k, v := range s.counters { result[k] = v } return result }
// snapshot 现在是一个拷贝 snapshot := stats.Snapshot() |