Golang의 init 함수

4839 단어
Golang의 init 함수
전재:https://zhuanlan.zhihu.com/p/34211611
골롱의main함수는 프로그램의 입구함수인 것을 모두가 알고 있으며main함수가 되돌아오면 프로그램도 끝난다.golang에는 또 다른 특수한 함수인 init 함수가main 함수보다 먼저 집행되고 패키지 단계의 일부 초기화 작업을 실현한다. 오늘 우리는 init의 특성을 깊이 있게 소개한다.
init 함수의 주요 역할:
  • 초기화는 초기화 표현식의 초기화 변수를 사용할 수 없습니다.
  • 프로그램 실행 전 등록.
  • sync를 실현한다.Once 기능.
  • 기타
  • init 함수의 주요 특징:
  • init 함수는main 함수보다 먼저 자동으로 실행되며 다른 함수에 호출될 수 없습니다.
  • init 함수에 입력 매개 변수, 반환 값이 없음;
  • 가방마다 여러 개의 init 함수가 있을 수 있다.
  • 패키지의 모든 원본 파일에도 여러 개의 init 함수가 있을 수 있다는 점은 비교적 특수하다.
  • 같은 가방의 init 실행 순서는 골랑이 명확하게 정의하지 않았기 때문에 프로그래밍을 할 때 프로그램이 이 실행 순서에 의존하지 않도록 주의해야 한다.
  • 서로 다른 가방의 init 함수는 가방이 가져온 의존 관계에 따라 집행 순서를 결정한다.

  • Golang 프로그램 초기화
    golang 프로그램의 초기화는main 함수보다 먼저 실행되고runtime에서 초기화됩니다. 초기화 순서는 다음과 같습니다.
  • 가져온 가방을 초기화한다. (가방의 초기화 순서는 가져온 순서('위에서 아래로')에 따라 실행되는 것이 아니다.runtime는 패키지 의존 관계를 분석해야 한다. 의존하지 않은 가방이 가장 먼저 초기화되고 변수 초기화 의존 관계와 유사하다.golang 변수의 초기화 참조).
  • 패키지 역할 영역의 변수를 초기화한다(이 역할 영역의 변수의 초기화도'위에서 아래로, 왼쪽에서 오른쪽'의 순서에 따라 런타임이 변수 의존 관계를 해석하고 의존하지 않은 변수가 가장 먼저 초기화되는 것은 아니다.golang 변수의 초기화 참조).
  • 실행 패키지의 init 함수;

  • 예 1:
    main.go
    package main                                                                                                                     
    
    import (
       "fmt"              
    )
    
    var T int64 = a()
    
    func init() {
       fmt.Println("init in main.go ")
    }
    
    func a() int64 {
       fmt.Println("calling a()")
       return 2
    }
    func main() {                  
       fmt.Println("calling main")     
    }
    

    출력:
    calling a()
    init in main.go
    calling main
    

    초기화 순서: 변수 초기화->init()->main()
    예 2:
    pack.go
    package pack                                                                                                                     
    
    import (
       "fmt"
       "test_util"
    )
    
    var Pack int = 6               
    
    func init() {
       a := test_util.Util        
       fmt.Println("init pack ", a)    
    } 
    

    test_util.go
    package test_util                                                                                                                
    
    import "fmt"
    
    var Util int = 5
    
    func init() {
       fmt.Println("init test_util")
    }  
    

    main.go
    package main                                                                                                                     
    
    import (
       "fmt"
       "pack"
       "test_util"                
    )
    
    func main() {                  
       fmt.Println(pack.Pack)     
       fmt.Println(test_util.Util)
    }
    

    출력:
    init test_util
    init pack  5
    6
    5
    

    패키지 초기화는test에 의존하기 때문에util, 따라서 실행할 때 테스트 초기화util 패키지 초기화하기;
    예 3:
    sandbox.go
    package main
    import "fmt"
    var _ int64 = s()
    func init() {
       fmt.Println("init in sandbox.go")
    }
    func s() int64 {
       fmt.Println("calling s() in sandbox.go")
       return 1
    }
    func main() {
       fmt.Println("main")
    }
    

    a.go
    package main
    import "fmt"
    var _ int64 = a()
    func init() {
       fmt.Println("init in a.go")
    }
    func a() int64 {
       fmt.Println("calling a() in a.go")
       return 2
    }
    

    z.go
    package main
    import "fmt"
    var _ int64 = z()
    func init() {
       fmt.Println("init in z.go")
    }
    func z() int64 {
       fmt.Println("calling z() in z.go")
       return 3
    }
    

    출력:
    calling a() in a.go
    calling s() in sandbox.go
    calling z() in z.go
    init in a.go
    init in sandbox.go
    init in z.go
    main
    

    같은 패키지의 다른 원본 파일의 init 함수 실행 순서는golangspec에서 설명하지 않았습니다. 상기 프로그램 출력을 보면 실행 순서는 원본 파일 이름의 사전 순서입니다.
    예 4:
    package main
    import "fmt"
    func init() {
       fmt.Println("init")
    }
    func main() {
       init()
    }
    

    init 함수를 호출할 수 없습니다. 위 코드는 다음과 같습니다:undefined: init
    예 5:
    package main
    import "fmt"
    func init() {
       fmt.Println("init 1")
    }
    func init() {
       fmt.Println("init 2")
    }
    func main() {
       fmt.Println("main")
    }
    

    출력:
    init 1
    init 2
    main
    

    init 함수는 비교적 특수해서 가방에서 여러 번 정의할 수 있습니다.
    예 6:
    var initArg [20]int
    func init() {
       initArg[0] = 10
       for i := 1; i < len(initArg); i++ {
           initArg[i] = initArg[i-1] * 2
       }
    }
    

    init 함수의 주요 용도: 초기화 표현식을 사용할 수 없는 변수를 초기화합니다
    예 7:
    import _ "net/http/pprof"
    Golang은 사용하지 않은 가져오기 패키지에 대해 오류를 컴파일하지만, 때때로 이 패키지의 init 함수만 호출하고, 패키지가 내보내는 변수나 방법을 사용하지 않을 때 위의 가져오기 방안을 사용합니다.
    상기 가져오기를 실행하면 init 함수는 이 프로세스의 실례적인 자원 점용 상황을 수집하고 http 서비스 인터페이스 방식으로 사용자에게 조회를 제공합니다

    좋은 웹페이지 즐겨찾기