2013-07-18 3 views
19

Go 패키지 A는 3 개의 .go 파일로 구성되며 각 파일의 다른 패키지 B의 기능을 사용합니다.Go 패키지 초기화

세 파일 각각의 시작 부분에 패키지 B를 가져와야하지만 패키지 B는 실제로 3 번 또는 1로 초기화 되었습니까?

답변

31

짧은 대답 : 초기화는 한 번만 수행됩니다.

긴 대답 : 관련 사양 섹션 인용 - Program execution을 :

없이 수입이있는 패키지는 모든 패키지 레벨의 변수에 초기 값을 할당 한 다음 이름으로 모든 패키지 레벨 함수를 호출하여 초기화

및 서명이

func init() 

으로 정의되어 있습니다. 이름이 init 인 패키지 범위 또는 파일 범위 식별자는이 서명이있는 함수로 선언되어야합니다. 단일 소스 파일 내에서도 이러한 여러 함수가 정의 될 수 있습니다. 그들은 불특정 순서로 실행됩니다.

패키지 수준에서 변수가 초기화되고 상수 값이 참조 순서에 따라 결정됩니다. A의 초기 값이 B에 의존하면 B 뒤에 A가 설정됩니다. 종속성 분석은 소스에있는 모양의 경우에만 초기화되는 항목의 실제 값입니다. A의 값에 B의 언급이 들어 있고, 이니셜 라이저가 B를 언급하거나 B를 언급하는 함수를 반복적으로 언급하는 값이 있으면 A는 B에 의존합니다. 이러한 종속성이주기를 형성하는 경우 오류입니다. 두 항목이 상호 의존적이지 않으면 컴파일러에 제시된대로 소스에 나타나는 순서대로, 가능하면 여러 파일로 초기화됩니다. 종속성 분석은 패키지마다 수행되므로 A의 이니셜 라이저가 B를 참조하는 다른 패키지에 정의 된 함수를 호출하면 불특정 결과가 생성 될 수 있습니다.

init 함수는 프로그램의 어느 곳에서나 참조 할 수 없습니다. 특히 init을 명시 적으로 호출 할 수 없으며 init에 대한 포인터를 함수 변수에 할당 할 수 없습니다.

패키지에 가져 오기가있는 경우 가져온 패키지는 패키지 자체를 초기화하기 전에 초기화됩니다. 여러 패키지가 패키지 P를 가져 오는 경우 P는 한 번만 초기화됩니다.

구성을 통한 패키지 가져 오기는 초기화에 순환 종속성이 없음을 보장합니다.

전체 패키지는 기본 패키지이라는 가져 오기되지 않은 단일 패키지를 가져 오는 모든 패키지와 함께 연결하여 만들어집니다. 주 패키지는 패키지 이름이 main이고, 인수가없고 값을 반환하지 않는 함수 main을 선언해야합니다.

func main() { … } 

프로그램 실행 main 함수를 호출 한 후 기본 패키지를 초기화하고 시작한다. 함수 main이 반환되면 프로그램이 종료됩니다. 다른 (non-main) goroutine이 완료 될 때까지 기다리지 않습니다.

패키지 초기화 - 변수 초기화 및 init의 호출은 한 번에 하나의 패키지로 순차적으로 단일 goroutine에서 발생합니다. init 함수는 초기화 코드와 동시에 실행할 수있는 다른 goroutine을 시작할 수 있습니다.그러나 초기화는 항상 init 함수를 순차 화합니다. 이전에 반환 될 때까지 다음 init을 시작하지 않습니다.

관련 문제