I'm not quite sure what “func literal” is, so this error confuses me a bit. I think I see the problem - I am referring to the range value variable from within the new go procedure, so the value may change at any time and not be what we expect. What is the best way to solve the problem?
The code in question:
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 }
My suggestion:
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 }
But is this really a solution to the problem? I just moved a link from a range variable to another local variable, the value of which is based on iteration for each loop that I am in.
source share