1

I have a type:

type Measure struct {
    Timestamp     time.Time
    Delta         float64
}

I am converting a slice of measures to a map with the timestamp as key:

func MeasuresToMap(measures []models.Measure) map[string]models.Measure {
    mapMeasures := make(map[string]models.Measure, len(measures)) //
    for _, measure := range measures {
        mapMeasures[measure.Timestamp.Format(time.RFC3339)] = measure
    }
    return mapMeasures
}

And I do:

mapMeasures := misc.MeasuresToMap(myMeasures)
for ts, _ := range mapMeasures {
        mapMeasures[ts].Delta = 0
    }

And I get:

Cannot assign to mapMeasures[ts].Delta

but what I can do:

for ts, measure := range mapMeasures {
        measure.Delta = 0
        mapMeasures[ts] = measure
    }

What is the difference between the 2 options, why can't I update directly Delta field ?

Anton
  • 1,793
  • 10
  • 20
Juliatzin
  • 18,455
  • 40
  • 166
  • 325

1 Answers1

0

You cannot assign to something you cannot get the address of.

That's the case with mapMeasures[ts].Delta = 0 - you cannot take the address of Measure. Here's what The Go Programming Language (A. Donovan, B. Kernighan) book has to say about taking an address of a map element:

One reason that we can’t take the address of a map element is that growing a map might cause rehashing of existing elements into new storage locations, thus potentially invalidating the address.

On the other hand, when you do for ts, measure := range mapMeasures {...} you create an explicit variable measure and therefore you're able to take its address and assign to it.

Anton
  • 1,793
  • 10
  • 20