for i := 0; i < 10; i++ {

        go func() {

                fmt.Println(i)

        }()

}


versus


for i := 0; i < 10; i++ {

        go func(i int) {

                fmt.Println(i)

        }(i)

}


이러한 형태가 동시성을 지원하는 언어라면 많이들 주의사항으로 나오는 형태 같네요.


반복문 안에서 동시적으로 실행되는 함수들에 변수를 전달 할 때

변수를 인수로 집어넣지 않고 클로저로 형태로 쓰면

값이 전달되는 게 아니라 레퍼런스가 전달되기 때문에

0부터 9까지 순서대로 출력하려 했던 위쪽 예제에서는 의도한 대로 작동하지 않는다.............라는 아주 유명한 상황인데요.


그런데 얼핏 생각하면 레퍼런스로 전달했다고 해도

각 함수들이 실행되는 시점에 따라서

최종값인 10이 아닌 7, 8, 9 등도 나올 수 있을 것 같은데 말이죠.

그리고 실행시마다 조금씩 달라야할 것 같고요.

즉, 루프가 완료되기 전에 실행되는 함수들이 있을 것도 같은데 말입니다.


그런데 무조건 최종값 10만 나오더라고요.

결국 루프에 대한 모든 평가가 끝나고 나서야 스택에 올라갔던(?) 함수들이 비로소 해결되기 시작하는 것 아닌가 싶더라고요.

그리고 제 기억에 Go만 그런게 아니라 다른 언어들에서도 그랬던 것 같아요.


제가 기초가 워낙 없어서 그런데 이거 이럴 수밖에 없는 건가요?

아니면 약속 같은 건가요?





실제 결과


10 10번 출력


제 의문


7 8 9 10 10 10 10 10 10 10

8 9 10 10 10 10 10 10 10 10 

등등은 왜 안 되는가


이게 for 반복에 의한 평가가 모두 이루어지고 나서야 for loop 내에서 실행하라고 시켰던 함수들이 실제 실행되기 때문인가

그렇다면 왜 바로 실행 안되고 기다렸다가 실행되는가