Go 애플리케이션이 실행될 때 모든 non-test 패키지는 특정 순서에 따라 초기화됩니다: 먼저 모든 의존성이(imported dependencies) 체인에 따라 초기화된 후, 실제 패키스가 초기화됩니다. 초기화는 다음을 사용하여 수행됩니다:
init 함수는 패키지 변수가 초기화된 후 호출됩니다. 패키지가 임포트되면, 해당 패키지의 변수를/함수를 사용하기 전에 init이 한 번 실행됩니다.
예시:
var a = getA() func getA() int { fmt.Println("getA 호출됨") return 42 } func init() { fmt.Println("init 호출됨") } // 출력: // getA 호출됨 // init 호출됨
특징:
다른 패키지의 init 함수를 명시적으로 호출할 수 있습니까?
답변: 아니요, init 함수는 프로그램 코드에서 직접 호출될 수 없습니다. 이는 패키지 초기화 과정에서 예측된 순간에만 런타임에 의해 호출되며, init()의 명시적인 호출은 허용되지 않으며, 컴파일 오류로 이어집니다.
이야기
프로젝트에서 두 패키지가 서로를 초기화하기 위해 서로를 임포트 했습니다(init()를 통해 글로벌 변수를 초기화하기 위해). 이로 인해 순환 의존성이 발생하였고, 빌드 시 오류가 발생했습니다 — Go는 초기화 순서를 결정할 수 없게 되었습니다.
이야기
복잡한 버그의 원인은 init 함수가 아직 초기화되지 않은 패키지의 글로벌 변수를 사용했기 때문이었습니다. 결과: 예측할 수 없는 상태에서의 모호한 동작.
이야기
프로젝트에서 사이드 이펙트를 위해 패키지를 명시적으로 사용하지 않고(import _ "some/lib") 임포트 했습니다. 코드 재구성 후, 필요한 패키지의 init 함수가 너무 일찍(다른 패키지의 의존 변수 초기화 전에) 호출되어 debug하기 힘든 버그가 발생했습니다.