Empfangen von Slices und Maps

Bitte beachten Sie, dass, wenn eine Map oder ein Slice als Funktionsparameter übergeben wird, Benutzer sie modifizieren können, wenn Sie darauf Bezug nehmen.

Nicht empfohlener Ansatz:

func (d *Driver) SetTrips(trips []Trip) {
  d.trips = trips
}

trips := ...
d1.SetTrips(trips)

// Versuchen Sie, d1.trips zu ändern?
trips[0] = ...

Empfohlener Ansatz:

func (d *Driver) SetTrips(trips []Trip) {
  d.trips = make([]Trip, len(trips))
  copy(d.trips, trips)
}

trips := ...
d1.SetTrips(trips)

// Hier ändern wir trips[0], aber es wird sich nicht auf d1.trips auswirken
trips[0] = ...

Zurückgeben von Slices oder Maps

Gleichzeitig sollten Sie darauf achten, dass Benutzer eine Map oder einen Slice modifizieren, die den internen Zustand freigibt.

Nicht empfohlener Ansatz:

type Stats struct {
  mu sync.Mutex
  counters map[string]int
}

// Snapshot gibt den aktuellen Zustand zurück
func (s *Stats) Snapshot() map[string]int {
  s.mu.Lock()
  defer s.mu.Unlock()

  return s.counters
}

// Der snapshot ist nicht mehr durch das Mutex geschützt
// daher unterliegt der Zugriff auf den snapshot einem Datenrennen und beeinflusst stats.counters
snapshot := stats.Snapshot()

Empfohlener Ansatz:

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 ist jetzt eine Kopie
snapshot := stats.Snapshot()