• Slices和Maps的边界拷贝操作
    • 接收Slices和Maps
    • 返回 Slices 和 Maps

    Slices和Maps的边界拷贝操作

    切片和 map 包含一个指针来指向底层数据,所以当需要复制他们时需要特别注意。

    接收Slices和Maps

    请记住,如果存储了对 slice 或 map 的引用,那么用户是可以对其进行修改。

    BadGood
    1. func (d Driver) SetTrips(trips []Trip) {
    2. d.trips = trips
    3. }
    4. trips :=
    5. d1.SetTrips(trips)
    6. // 是想修改 d1.trips 吗?
    7. trips[0] =
    1. func (d Driver) SetTrips(trips []Trip) {
    2. d.trips = make([]Trip, len(trips))
    3. copy(d.trips, trips)
    4. }
    5. trips :=
    6. d1.SetTrips(trips)
    7. // 修改 trips[0] 并且不影响 d1.trips 。
    8. trips[0] =

    返回 Slices 和 Maps

    同理,谨慎提防用户修改暴露内部状态的 slices 和 maps 。

    BadGood
    1. type Stats struct {
    2. sync.Mutex
    3. counters map[string]int
    4. }
    5. // Snapshot 返回当前状态
    6. func (s Stats) Snapshot() map[string]int {
    7. s.Lock()
    8. defer s.Unlock()
    9. return s.counters
    10. }
    11. // snapshot 不再受锁保护了!
    12. snapshot := stats.Snapshot()
    1. type Stats struct {
    2. sync.Mutex
    3. counters map[string]int
    4. }
    5. func (s Stats) Snapshot() map[string]int {
    6. s.Lock()
    7. defer s.Unlock()
    8. result := make(map[string]int, len(s.counters))
    9. for k, v := range s.counters {
    10. result[k] = v
    11. }
    12. return result
    13. }
    14. // snapshot 是一分拷贝的内容了
    15. snapshot := stats.Snapshot()