Go의 클로져를 사용할 때의 흔한 실수와 이유, 해결책

클로져는 함수 리터럴이다. 함수 리터럴은 자신을 감싸는 함수의 변수를 참조할 수 있다. 내가 느끼기에 고의 클로져는 자바스크립트의 클로져와 동일하다고 생각된다. 클로져의 쓰임새는 매우 다양하지만 초보자들에겐 약간의 혼동을 주기도 한다.

(나를 포함해서) 개발자들이 주로 하는 실수는 다음과 같이 루프 안에서 클로져를 생성할 때 생긴다.


이 클로져는 예상대로 동작하지 않는다. 왜일까.

클로져가 만들어질 때 클로져는 for 의 변수 i를 참조해서 messages 슬라이스에 접근했다. 클로져들이 만들어 질 때 참조한 변수 i는 이 클로져들이 생성된 후, 즉 루프가 끝났을 때 4가 되었다.
다음 루프에서 클로져를 호출 했을 때 i는 4이고 messages[i]는 you? 이다.

해결책은 두번째 코드에서 보여주고 있는데 여기에서 처럼 클로져가 만들어 질 때마다 새로운 변수를 만들도록 프로그램을 고치면 된다.
세번째 코드 블록은 같은 이름의 변수를 재선언 하는데 이렇게 하면 j와 같은 새로운 변수를 만들 필요없이 루프 내에서만 참조가능한 i를 만들게 되고 실제로 이 i는 외부의 i와 같은 의미와 값을 가지므로 헷갈리지도 않는다. 고 언어에서 흔히 사용되는 방법이다.