Проблема проста: у вас есть кусочек driver
с:
var Drivers []driver
Обратите внимание, что Drivers
- это фрагмент некоторого типа структуры, а не фрагмент указателей!
Когда вы добавляете что-то (или присвоить значение одного из его элементов):
Drivers = append(Drivers, driver)
Это делает копию значения приложенном (или назначенный)! Так что, когда вы сделаете это позже:
driver.variables = make(map[string]string)
Он будет устанавливать новое значение карты в driver.variables
, но отличается от значения, хранящегося в Drivers
(точнее в Drivers[0]
).
Позже вы заполните driver.variables
, но вы распечатаете Drivers[0].variables
. Они представляют собой две разные значения структуры, с двумя разными значениями карты. Goroutines не играют здесь роли (они должным образом синхронизированы, поэтому они не должны в любом случае).
ли вы напечатать driver.variables
:
fmt.Print(driver.variables)
Вы бы видели (попробуйте на Go Playground):
map[a:b]
Если закомментировать эту строку:
driver.variables = make(map[string]string) // Commenting this line makes it work, too
Это будет работать, , но только потому, что, хотя у вас есть 2 значения структуры, они имеют одинаковое значение карты (тот же заголовок карты, указывающий на одну и ту же структуру данных карты).
Вы также можете заставить его работать, если вы звоните driver.populate()
по значению STRUCT Drivers[0]
(и прилипание к печати Drivers[0].variables
):
go Drivers[0].populate(done)
// ...
fmt.Print(Drivers[0].variables)
Попробуйте это на Go Playground.
И вы также можете заставить его работать, если Drivers
является срез указателей:
var Drivers []*driver
// ...
driver := &driver{
variables: make(map[string]string),
}
Поскольку driver
и Driver[0]
будет такой же указатель (вы будете иметь только одно значение структуры и одно значение карты в качестве начального карта больше недоступна). Попробуйте это на Go Playground.
Правильный ответ: goroutines в этом случае не имеют значения: https://play.golang.org/p/Eh3gPbFWPL показывает проблему с только главной горутином; понимая, что struct _copied_, но указатели (и ссылочные типы, такие как карта) являются общими, что вызывает здесь проблему. – val