1. 程式人生 > >golang中的init函數以及main函數

golang中的init函數以及main函數

data- 文件 -s 可選 data golang 例子 用戶 一次

首先我們看一個例子:init函數:

init 函數可在package main中,可在其他package中,可在同一個package中出現多次。

main函數

main 函數只能在package main中。

執行順序

golang裏面有兩個保留的函數:init函數(能夠應用於所有的package)和main函數(只能應用於package main)。這兩個函數在定義時不能有任何的參數和返回值。

雖然一個package裏面可以寫任意多個init函數,但這無論是對於可讀性還是以後的可維護性來說,我們都強烈建議用戶在一個package中每個文件只寫一個init函數。

go程序會自動調用init()和main(),所以你不需要在任何地方調用這兩個函數。每個package中的init函數都是可選的,但package main就必須包含一個main函數。

程序的初始化和執行都起始於main包。

如果main包還導入了其它的包,那麽就會在編譯時將它們依次導入。有時一個包會被多個包同時導入,那麽它只會被導入一次(例如很多包可能都會用到fmt包,但它只會被導入一次,因為沒有必要導入多次)。

當一個包被導入時,如果該包還導入了其它的包,那麽會先將其它包導入進來,然後再對這些包中的包級常量和變量進行初始化,接著執行init函數(如果有的話),依次類推。

等所有被導入的包都加載完畢了,就會開始對main包中的包級常量和變量進行初始化,然後執行main包中的init函數(如果存在的話),最後執行main函數。下圖詳細地解釋了整個執行過程: 技術分享圖片

首先我們看一個例子:

代碼結構:

技術分享圖片

Lib1.go

package InitLib1

import "fmt"

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

Lib2.go

package InitLib2

import "fmt"

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

main.go

package main

import (
    "fmt"
    _ "GolangTraining/InitLib1"
    _ "GolangTraining/InitLib2"
)

func init() {
    fmt.Println(
"libmain init") } func main() { fmt.Println("libmian main") }

代碼很簡單,只是一些簡單的輸出

lib1
lib2
libmain init
libmian main

輸出的順序與我們上面圖給出的順序是一致的

那我們現在就改動一個地方,Lib1包導入Lib2,main包不管
Lib1
package InitLib1

import (
    "fmt"
    _ "GolangTraining/InitLib2"
)

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

輸出:

lib2
lib1
libmain init
libmian main

main包以及Lib1包都導入了Lib2,但是只出現一次,並且最先輸出,

說明如果一個包會被多個包同時導入,那麽它只會被導入一次,而先輸出lib2是因為main包中導入Lib1時,Lib1又導入了Lib2,會首先初始化Lib2包的東西

golang中的init函數以及main函數