3 ms·
for _, informer := range c.informerMap { informer := informer go informer.Run(stopCh) } for _, a := range alarms { a := a
by assbuttbuttass 3y ago
for _, informer := range c.informerMap {
informer := informer
go informer.Run(stopCh)
}
for _, a := range alarms {
a := a
go a.Monitor(b)
}
Not sure what the difference could be, but let me take a guess. In one case, the loop variable is a pointer, and in the other case a value. The method call uses a pointer receiver, so in the value case the compiler automatically inserts a reference to the receiver?
- thebears5454 3y agoIt's definitely something like that where the compiler knows to grab the value.
- Cthulhu_ 3y agoI'm looking at the naming, the top one is a map, the bottom one is a slice; that's where my internal knowledge ends though. I know a slice will have a backing array on the heap so there's some pointers / references involved.
- pdimitar 3y agoSince iterating on maps in Go always results in copying the value then I'd guess the first piece of code does what is expected due to that, and the second does not because `a` will only ever have the value of the last element of `alarms` (the original problem described in the article).
- assbuttbuttass 3y agoI managed to track down the original code containing these snippets using the GitHub code search tool: https://github.com/adobe/kratos/blob/93246f92d53feba73743dbf3384e7044e9a05ea9/scale/scale_target.go#L98 https://github.com/adobe/kratos/blob/93246f92d53feba73743dbf... https://github.com/StalkR/goircbot/blob/6081ed5d1d74f01767d70a1b3d5052d2fab42478/plugins/df/handlers.go#L110 https://github.com/StalkR/goircbot/blob/6081ed5d1d74f01767d7... The difference is that in one case, informer is an interface, so the method call resolves informer.Run immediately and there's no issue. In the other case, a is a struct Alarm, and gets copied by value, and the Monitor method takes a pointer receiver. So my original intuition was right, the compiler is essentially translating go a.Monitor(b) into go (&a).Monitor(b) Which has a reference to the loop variable, and creates an issue.
- mighmi 3y agoCf. https://www.youtube.com/watch?v=0m6iFd9N_CY https://www.youtube.com/watch?v=0m6iFd9N_CY which features this code: func soldAnother(a *album) { a.copies++ // note the pointer. Can use dot notation on pointer, // equivalent to (*a).copies++)