go init()執(zhí)行順序

go允許定義多個(gè)init(),多個(gè)init()會(huì)涉及到執(zhí)行先后的問(wèn)題,本文將詳細(xì)講解這個(gè)問(wèn)題.

概述

init()一般用來(lái)做一些初始化工作, go允許定義多個(gè)init(),根據(jù)init()重復(fù)場(chǎng)景不同,可以分為

  • 同文件 單文件中定義多個(gè)init()
  • 同模塊 同模塊下不同文件中定義了多個(gè)init()
  • 子模塊 本模塊和子模塊都包含init()
  • 跨模塊 多個(gè)被引用模塊中均含init()

要點(diǎn)秘訣:

  1. 涉及引用時(shí),先加載的先執(zhí)行
  2. 同一文件中,先定義的先執(zhí)行

同文件

一個(gè)文件中出現(xiàn)多個(gè)init()時(shí),執(zhí)行順序是從上往下按照定義順序執(zhí)行的,先定義的執(zhí)行.

package main

import "fmt"

func main(){

}

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

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

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

執(zhí)行結(jié)果

first...
second...
third...

調(diào)整一下定義順序

package main

import "fmt"

func main() {

}

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

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

執(zhí)行結(jié)果

third...
second...
first...

同模塊

同模塊下定義多個(gè)init(),執(zhí)行順序是根據(jù)文件加載順序來(lái)執(zhí)行的,文件加載順序就是文件名的字符串排序.

代碼測(cè)試一下,新建一個(gè)模塊websit,目錄結(jié)構(gòu)如下

  • |---src
    • |---websit
      • |---acfun.go
      • |---bilibili.go
  • |---main.go

main.go內(nèi)容如下

package main

import (
    _ "website"
)

func main() {

}

acfun.go內(nèi)容如下

package website

import "fmt"

func init() {
    fmt.Println("AcFun彈幕視頻網(wǎng) - 認(rèn)真你就輸啦 (?ω?)ノ- ( ...")
}

bilibili.go內(nèi)容如下
``go
package website

import "fmt"

func init(){
fmt.Println("嗶哩嗶哩 (゜-゜)つロ 干杯~-bilibili")
}

運(yùn)行結(jié)果為
```text
AcFun彈幕視頻網(wǎng) - 認(rèn)真你就輸啦 (?ω?)ノ- ( ...
嗶哩嗶哩 (゜-゜)つロ 干杯~-bilibili

文件名排序,acfun.gobilibili.go之前,所以acfun.go會(huì)先被加載,文件中的init()會(huì)先被執(zhí)行.

如果acfun.go中定義了多個(gè)init(),執(zhí)行順序和同文件一樣.

子模塊

與同模塊一樣,先被加載的先執(zhí)行.

修改上述demo文件路徑,增加個(gè)子模塊login.

  • |---src
    • |---websit
      • |---login
        • |----login.go
      • |---acfun.go
      • |---bilibili.go
  • |---main.go

login.go內(nèi)容如下

package login

import "fmt"

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

修改acfun.go

package website

import (
    "fmt"
    _ "website/login"
)

func init() {
    fmt.Println("AcFun彈幕視頻網(wǎng) - 認(rèn)真你就輸啦 (?ω?)ノ- ( ...")
}

執(zhí)行結(jié)果:

login...
AcFun彈幕視頻網(wǎng) - 認(rèn)真你就輸啦 (?ω?)ノ- ( ...
嗶哩嗶哩 (゜-゜)つロ 干杯~-bilibili

ps:go模塊加載詳解請(qǐng)查閱另外一篇文章.

多模塊

  1. 同子模塊一樣,哪個(gè)模塊先被import就先被加載.
  2. 這個(gè)模塊如果有子模塊,會(huì)先加載子模塊
  3. 如果子模塊中有多個(gè)文件,根據(jù)文件名排序決定文件加載順序
  4. 一個(gè)文件被加載時(shí),如果定義多個(gè)init(),先定義的先執(zhí)行.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容