프로그램 초기화

프로그램 초기화

완성된 Go 프로그램을 실행하면 main 함수부터 실행될 거라고 생각하기 쉬워요. 그런데 실제로는 그 전에 할 일이 하나 남아 있어요. 바로 프로그램에 포함된 모든 패키지를 초기화하는 단계죠. 이 초기화가 어떤 순서로, 어느 한 곳에서 진행되는지 알면 Go가 패키지를 다루는 방식을 훨씬 또렷하게 이해할 수 있어요. 지금부터 차근차근 살펴볼게요.

출처: Go Specification

본문

완성된 프로그램의 패키지들은 단계적으로, 한 번에 한 패키지씩 초기화돼요. 패키지가 import를 갖고 있다면, 그 패키지 자신이 초기화되기 전에 import한 패키지들이 먼저 초기화되죠. 여러 패키지가 같은 패키지를 import하더라도 그 패키지는 딱 한 번만 초기화돼요. 그리고 import의 구조가 성립되는 방식 자체가, 초기화 의존성이 순환(cycle)을 이루는 일은 아예 생길 수 없다는 걸 보장해 줘요. 조금 더 정확히 말해볼게요.

모든 패키지를 import 경로(import path) 순서대로 정렬한 목록을 떠올려 보세요. 각 단계에서, 목록에서 아직 초기화되지 않은 패키지를 찾는데, 그 조건은 '이 패키지가 (있다면) import하는 모든 패키지가 이미 초기화되었을 것'이에요. 그 조건을 처음으로 만족하는 패키지를 초기화해요. 이 단계를 모든 패키지가 초기화될 때까지 반복하면 돼요.

패키지 초기화, 즉 변수 초기화와 init 함수의 호출은 단 하나의 고루틴(goroutine) 안에서, 순차적으로, 한 패키지씩 진행돼요. init 함수는 다른 고루틴을 띄울 수도 있고, 그 고루틴들은 초기화 코드와 동시에(concurrently) 실행될 수 있어요. 다만 주의할 점이 하나 있어요. 초기화는 항상 init 함수들을 순서대로 진행한다는 거예요. 앞선 init 함수가 반환(return)하기 전에는 다음 init 함수를 호출하지 않아요.

더 알아보기