- Slices和Maps的边界拷贝操作
- 接收Slices和Maps
- 返回 Slices 和 Maps
Slices和Maps的边界拷贝操作
切片和 map 包含一个指针来指向底层数据,所以当需要复制他们时需要特别注意。
接收Slices和Maps
请记住,如果存储了对 slice 或 map 的引用,那么用户是可以对其进行修改。
| Bad | Good |
|---|
func (d Driver) SetTrips(trips []Trip) { d.trips = trips}trips := …d1.SetTrips(trips)// 是想修改 d1.trips 吗?trips[0] = …
|
func (d Driver) SetTrips(trips []Trip) { d.trips = make([]Trip, len(trips)) copy(d.trips, trips)}trips := …d1.SetTrips(trips)// 修改 trips[0] 并且不影响 d1.trips 。trips[0] = …
|
返回 Slices 和 Maps
同理,谨慎提防用户修改暴露内部状态的 slices 和 maps 。
| Bad | Good |
|---|
type Stats struct { sync.Mutex counters map[string]int}// Snapshot 返回当前状态func (s Stats) Snapshot() map[string]int { s.Lock() defer s.Unlock() return s.counters}// snapshot 不再受锁保护了!snapshot := stats.Snapshot()
|
type Stats struct { sync.Mutex counters map[string]int}func (s Stats) Snapshot() map[string]int { s.Lock() defer s.Unlock() result := make(map[string]int, len(s.counters)) for k, v := range s.counters { result[k] = v } return result}// snapshot 是一分拷贝的内容了snapshot := stats.Snapshot()
|