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 내에서 실행하라고 시켰던 함수들이 실제 실행되기 때문인가
그렇다면 왜 바로 실행 안되고 기다렸다가 실행되는가
무슨 개소리야 함수별로 각각 전용 결과 변수에 대한 레퍼런스를 전달해 주면 아무런 문제도 발생 안 하지. 오히려 그게 제일 쉬운 방법일 때는 그렇게 하고
보통 이런 예를 들때 가장 쉽게 숫자 순서대로 출력하는 예 들어주잖아요. 그런데 최종값만 출력되는. 그 이유가 레퍼런스로 전달되서이고. 이런 예제에서는 의도대로 동작 안 한 거죠. 상황에 상관없이 레퍼런스로 전달하면 안된다는 얘기를 하는게 아니라.
아 그 얘기임? ㅇㅋ
제가 본문에 마치 제너럴한 상황에서 그런 것처럼 써놨네요. 암튼 궁금한 것은 그 다음 ㅠㅠ
정확히 어떻게 결과가 나온다는건지 좀 알려줘. GO 문법을 몰라서 잘 파악이 안됨
결과 : 10 10 10 10 10 10 ... 의문 : 왜 7 8 9 10 10 10 ... 등이 아닌가입니다
모모링러브//되서->돼서 (되어 = 돼임) [리듬 맞춤법 봇♬]
제 전제부터가 틀렸네요. 가끔 10 아닌 거 나옵니다. ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ