1. 程式人生 > >goinit函式詳解

goinit函式詳解

init()函式會在每個包完成初始化後自動執行,並且執行優先順序比main函式高。init 函式通常被用來:

  • 對變數進行初始化
  • 檢查/修復程式的狀態
  • 註冊
  • 執行一次計算

 

包的初始化

       為了使用匯入的包,首先必須將其初始化。初始化總是以單執行緒執行,並且按照包的依賴關係順序執行。這通過Golang的執行時系統控制,如下圖所示:

  1. 初始化匯入的包(遞迴匯入)
  2. 對包塊中宣告的變數進行計算和分配初始值
  3. 執行包中的init函式

 

initial.go

package main

import "fmt"

var _ int64=s()

func init(){
    fmt.Println("init function --->")
}

func s() int64{
    fmt.Println("function s() --->")
    return 1
}

func main(){
    fmt.Println("main --->")
}

執行結果

function s() --->
init function --->
main --->

      即使包被匯入多次,初始化只需要一次。

 

特性

      init函式不需要傳入引數,也不會返回任何值。與main相比而言,init沒有被宣告,因此也不能被引用。

package main

import "fmt"

func init(){
    fmt.Println("init")
}

func main(){
    init()
}

     在編譯上面的函式時,會出錯“undefined:init”。每個原始檔中可以包含多個init函式

package main

import "fmt"

func init(){
    fmt.Println("init 1")
}

func init(){
    fmt.Println("init2")
}

func main(){
    fmt.Println("main")
}

/*執行結果:
init1
init2
main */

       從上面的例子中,可以看出每個原始檔可以包含多個init函式。 
       init函式常用的一個例子就是用來設定初始表示式的值。

var precomputed=[20]float64{}

func init(){
    var current float64=1
    precomputed[0]=current
    for i:=1;i<len(precomputed);i++{
        precomputed[i]=precomputed[i-1]*1.2
    }
}

        因為上面程式碼中不可能用for迴圈來作為precomputed的值(這是一句宣告),因此可以用init函式來解決這個問題。

Go包匯入規則的副作用

     Go要求非常嚴格,不允許引用不使用的包。但是有時你引用包只是為了呼叫init函式去做一些初始化工作。此時空識別符號(也就是下劃線)的作用就是為了解決這個問題。

import _ "image/png"