Variable captured by func literal


it’s a common mistake for new comers in Go, and yes the var currentProcess changes for each loop, so your goroutines will use the last process in the slice l.processes, all you have to do is pass the variable as a parameter to the anonymous function, like this:

func (l *Loader) StartAsynchronous() []LoaderProcess {

    for ix := range l.processes {

        go func(currentProcess *LoaderProcess) {

            cmd := exec.Command(currentProcess.Command, currentProcess.Arguments...)
            log.LogMessage("Asynchronously executing LoaderProcess: %+v", currentProcess)

            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)

            time.Sleep(time.Second * TIME_BETWEEN_SUCCESSIVE_ITERATIONS)

        }(&l.processes[ix]) // passing the current process using index


    return l.processes

Another example :

Go features


  1. In Go a type definition is neither pointer nor value, it’s just a type.
  2. Go doesn’t have classes
  3. Go doesn’t have inheritance, it has interfaces for polymorphism and some sugar for automatic delegation (“struct embedding”).
  4. Simple build system. Want to compile for linux arm from your MacBook? GOOS=linux GOARCH=arm go build.
  5. Implicit interfaces.
  6. Great standard library. Go’s standard library covers JSON, Templating, HTTP (production grade), testing, benchmarking, etc, etc.
  7. Standard formatting.
  8. Documentation for free.