❓ 질문:
for i := 0; i < 100; i++ 루프 안에서 고루틴을 이렇게 작성했을 때:
go func() {
fmt.Println(i)
}()
왜 때때로 출력이 100, 100, 100... 처럼 잘못된 값이 나오는 거야?
✅ 답변:
이건 Go에서 클로저가 외부 변수 i를 참조하기 때문이야.
- go func() { ... }() 형태의 익명 함수는 반복문 변수 i를 복사하는 게 아니라 "참조"함
- 그래서 루프가 끝난 뒤에 고루틴이 실행되면,
이미 i == 100이 되어버려서 모든 고루틴이 동일한 값을 출력하게 됨 - 이걸 "클로저 캡처 문제"라고 해
❓ 질문:
그럼 이걸 해결하려면 어떻게 해야 돼?
✅ 답변:
반복문 변수 i를 함수 매개변수로 넘겨서 "복사본"을 만들어야 해.
예를 들어:
for i := 0; i < 100; i++ {
go func(n int) {
fmt.Println(n)
}(i)
}
- 이렇게 하면 i의 현재 값이 n으로 복사되어 고루틴 내부에서 안전하게 사용 가능
- 따라서 각 고루틴이 자기 고유의 n 값을 출력하게 돼 → 0 ~ 99 정상 출력
✅ 요약
잘못된 패턴 (캡처 발생) | 안전한 패턴 (값 복사) |
go func() { fmt.Println(i) }() | go func(n int) { fmt.Println(n) }(i) |
필요하면, 반복문 변수의 클로저 복사 패턴을 i := i 형태로 처리하는 또 다른 안전 패턴도 알려줄게 😄
지금까지 정말 잘 따라오고 있어!
'언어 및 도구들 공부 > Go' 카테고리의 다른 글
Go) for 와 range (0) | 2025.04.07 |
---|---|
Go) 클로저 캡처 문제 + 고루틴 동작 순서 (0) | 2025.04.06 |
Go) ready 상태 channel이 복수면? (0) | 2025.04.06 |
Go) Channel, select 2 (0) | 2025.04.06 |
Go) Channel, select (0) | 2025.04.06 |