The problem is simple: you have a slice of driver
s:
var Drivers []driver
Note that Drivers
is a slice of some struct type, not a slice of pointers!
When you append something (or you assign a value to one of its elements):
Drivers = append(Drivers, driver)
That makes a copy of the value appended (or assigned)! So when you do this later:
driver.variables = make(map[string]string)
It will set a new map value to driver.variables
, but that is distinct from the value stored in Drivers
(more precisely at Drivers[0]
).
Later you populate driver.variables
, but you print Drivers[0].variables
. They are 2 different struct values, with 2 different map values. Goroutines do not play a role here (they are properly synchronized so they shouldn't anyway).
Would you print driver.variables
:
fmt.Print(driver.variables)
You would see (try it on the Go Playground):
map[a:b]
If you comment out this line:
driver.variables = make(map[string]string) // Commenting this line makes it work, too
It would work, but only because even though you have 2 struct values, they have the same map value (same map header pointing to the same map data structure).
You can also make it work if you call driver.populate()
on the struct value Drivers[0]
(and sticking to printing Drivers[0].variables
):
go Drivers[0].populate(done)
// ...
fmt.Print(Drivers[0].variables)
Try this one on the Go Playground.
And you can also make it work if Drivers
is a slice of pointers:
var Drivers []*driver
// ...
driver := &driver{
variables: make(map[string]string),
}
Because driver
and Driver[0]
will be the same pointer (you will have only one struct value and one map value as the initial map is not accessible anymore). Try this on the Go Playground.