Я не совсем уверен, что это 'func literal', таким образом, эта ошибка меня немного сбивает с толку. Я думаю, что вижу проблему - я ссылаюсь на переменную значения диапазона изнутри новой процедуры go, поэтому значение может измениться в любое время и не быть тем, что мы ожидаем. Каков наилучший способ решить проблему?Перейдите в переменную ветеринга, захваченную func literal при использовании процедуры go внутри внутри каждого цикла
Код в вопросе:
func (l *Loader) StartAsynchronous() []LoaderProcess {
for _, currentProcess := range l.processes {
cmd := exec.Command(currentProcess.Command, currentProcess.Arguments...)
log.LogMessage("Asynchronously executing LoaderProcess: %+v", currentProcess)
go func() {
output, err := cmd.CombinedOutput()
if err != nil {
log.LogMessage("LoaderProcess exited with error status: %+v\n %v", currentProcess, err.Error())
} else {
log.LogMessage("LoaderProcess exited successfully: %+v", currentProcess)
currentProcess.Log.LogMessage(string(output))
}
time.Sleep(time.Second * TIME_BETWEEN_SUCCESSIVE_ITERATIONS)
}()
}
return l.processes
}
предложил мой фикс:
func (l *Loader) StartAsynchronous() []LoaderProcess {
for _, currentProcess := range l.processes {
cmd := exec.Command(currentProcess.Command, currentProcess.Arguments...)
log.LogMessage("Asynchronously executing LoaderProcess: %+v", currentProcess)
localProcess := currentProcess
go func() {
output, err := cmd.CombinedOutput()
if err != nil {
log.LogMessage("LoaderProcess exited with error status: %+v\n %v", localProcess, err.Error())
} else {
log.LogMessage("LoaderProcess exited successfully: %+v", localProcess)
localProcess.Log.LogMessage(string(output))
}
time.Sleep(time.Second * TIME_BETWEEN_SUCCESSIVE_ITERATIONS)
}()
}
return l.processes
}
Но делает действительно решить эту проблему? Я только что переместил ссылку из переменной диапазона в другую локальную переменную, значение которой основано на итерации для каждого цикла, в котором я находится.
Спасибо за обновленный код, который выглядит великолепно! У меня была грубая ошибка в моем коде, которая заняла более часа, чтобы исправить что-то очень похожее. Я возвращал [] * LoaderProcess, прежде чем не понял, что срез уже является указателем, поэтому я по существу возвращал кусочек указателей, где каждый указатель указывал на тот же экземпляр LoaderProcess, который оказался последней командой для завершения. Каждый раз каждый раз после выполнения. Итак, два больших урока извлечены из одного фрагмента кода. Спасибо. – anon58192932