Skip to content

Iterate go routine with an anonymous function #37297

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gonyyi opened this issue Feb 19, 2020 · 2 comments
Closed

Iterate go routine with an anonymous function #37297

gonyyi opened this issue Feb 19, 2020 · 2 comments

Comments

@gonyyi
Copy link

gonyyi commented Feb 19, 2020

What version of Go are you using (go version)?

--> go version go1.13 darwin/amd64

Does this issue reproduce with the latest release?

--> Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/gonyi/Library/Caches/go-build"
GOENV="/Users/gonyi/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY="github.com/gonyyi"
GONOSUMDB="github.com/gonyyi"
GOOS="darwin"
GOPATH="/Users/gonyi/go"
GOPRIVATE="github.com/gonyyi"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/jn/9zs9p73j7_gf3mzpdx4frmmd_05z01/T/go-build626678608=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

work := []string{"1mail", "2commute", "3coding", "4debugging", "5coffee"}
for _, v := range work {
	go func(){
		fmt.Println(v)
	}()
}

I was doing simple iteration of work thru channel with go routine.
I was expect WORK function will receive those 5 items, however, it was repeating likely last item in the work slice as below.

5coffee
5coffee
5coffee
5coffee
5coffee

But, instead of having anonymous in for-loop, if I call outside function, it gives expected result:

work := []string{"1homework", "2commute", "3coding", "4debugging", "5coffee"}
for _, v := range work {
	go fmt.Println(v)
	//go func(){
	//	fmt.Println(v)
	//}()
}

I think this is by the design, but I wonder if it makes more sense to have identical result..

What did you expect to see?

1homework
4debugging
5coffee
2commute
3coding

What did you see instead?

5coffee
5coffee
5coffee
5coffee
5coffee
@ALTree
Copy link
Member

ALTree commented Feb 19, 2020

Hi,

the difference is that your first snippet is go-running a closure, while the second is not. (and the Println argument is evaluated immediately, even if the function is called later).

See: https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables

This is unlikely to change, so I'm closing this issue.

@ALTree ALTree closed this as completed Feb 19, 2020
@D1CED
Copy link

D1CED commented Feb 19, 2020

If you run go vet—gos build in linter—it tells you about your mistake.

Here is your example in the playground which runs go lint when compiling: https://play.golang.org/p/7VnPfqpf_50

@golang golang locked and limited conversation to collaborators Feb 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants