Wrapping a function call into a closure when using goroutines


Wrapping a function call into a closure leads to an unexpected behaviour when using goroutines.

Consider the following example:

package main

import (

var workerNum = 5
var wg sync.WaitGroup

func block() {
    dur := 300 * time.Millisecond
    select {
    case <- time.After(dur): {}

func startWorker(worker int) {
    for i:=0; i < 3; i++{
        log.Printf("Worker %d woke up! \n", worker)

func main() {
    for i:=0; i < workerNum; i++ {
        //go func() { startWorker(i) }()
        go startWorker(i)


Test it here: http://play.golang.org/p/nMlnTkbwVf

One can see that wrapping startWorker(i) into func() { startWorker(i) }() results in calling only the 5-th worker.

It looks like there is something wrong in the way how closures capture variables from the outer scope. Why is this happening? Do closures use pass-by-reference way for passing outer variables instead of pass-by-value?


That’s how closures in all languages work, if you want to do it that way, you have to isolate the variable.

go func(i int) { startWorker(i) }(i)

Answered By – OneOfOne

Answer Checked By – Timothy Miller (GoLangFix Admin)

Leave a Reply

Your email address will not be published.