go學習筆記-init函數執行順序分析

golang中有個神奇的函數init,該函數會在全部程序執行開始前被調用,每一個包能夠包含多個init函數,全部被編輯器識別到的init函數都會在main函數執行前被調用。一般被用來註冊一個程序須要使用的依賴,如mysql註冊,配置文件加載等。mysql

在main包的使用
package main
import "fmt"
func main()  {
    fmt.Println("這裏是mian")
}
func  init()  {
    fmt.Println("這裏是Init1")
}
func  init()  {
    fmt.Println("這裏是Init2")
}
//輸出結果
這裏是Init1
這裏是Init2
這裏是main

一個很簡單的示例,能夠看到init函數是在main函數執行以前被執行的,而且一個包能夠有多個init函數golang

在其餘包中使用
  • main包
package main
import (
    "fmt"
    "test/services"
)
func main()  {
    fmt.Println("這裏是main")
    services.Run()
}
func  init()  {
    fmt.Println("這裏是main init")
}
  • services包
package services
import "fmt"
func Run()  {
    fmt.Println("這裏是 services run")
}
func init()  {
    fmt.Println("這裏是 services裏面的init")
}
  • 結果
這裏是 services裏面的init
這裏是main init
這裏是main
這裏是 services run

能夠看到這裏先執行了services包裏面的init,在執行的maininit。這是由於在編譯的時候會先去檢查導入的包,首先發現其餘包裏面的init,而後纔會到main包裏面的init。那若是services裏面又包含了其餘的包呢?其餘包裏面又在不一樣的文件中有不的init呢?下面咱們一塊兒來看看到底init的順序是怎麼樣的。sql

多個包嵌套

在上面的基礎上增長third編輯器

  • 目錄結構
---services
-----service.go
---third
-----third_a.go
-----third_b.go
---main.go
  • third_a.go
package third
import "fmt"
func TestA()  {
}
func init()  {
    fmt.Println("這裏是 third  init a")
}
  • third_b.go
package third
import "fmt"
func TestB()  {
}
func init()  {
    fmt.Println("這裏是 third  init b")
}
  • serice.go
package services
import (
    "fmt"
    "test/third"
)
func Run()  {
    fmt.Println("這裏是 services run")
    third.TestB() // 先調用 testB
    third.TestA() // 在調用 testA
}
func init()  {
    fmt.Println("這裏是 services裏面的init")
}
  • 結果
這裏是 third init a
這裏是 third init b
這裏是 services裏面的init
這裏是 main init
這裏是 main
這裏是 services run

能夠看到這裏先執行了 third_a中的init,再執行了third_b中的init,而不是按照咱們函數的調用順序來執行的,那麼是按照文件的排序來定的?我以爲應該是這樣的,官方只是說按源文件的順序執行,具體是不是這樣只有靠實際實踐來看,目前來看是這樣的順序。其實咱們大可沒必要糾結太多的順序問題。函數

咱們只須要知道,每一個包中能夠有多個init函數,而其餘包的init是在main包的init調用以前被執行,main函數最後執行便可,若是非要有依賴的順序關係,那麼能夠在init中 包含調用便可spa

期待一塊兒交流

qrcode_for_gh_60813539dc23_258.jpg

相關文章
相關標籤/搜索