Go包中程式碼執行順序
近來無事,研究了一下Go語言包中程式碼的執行順序,研究完之後別有一番收穫。
廢話不多說,直接上程式碼。
工程目錄結構
init
src
d
d.go
k.go
a.go
main.go
z.go
其中main.go是入口檔案
貼出檔案中的程式碼
d.go
package d
import "fmt"
var _ int64 = D()
func init() {
fmt.Println("init in d.go")
}
func D() int64 {
fmt.Println("calling d() in a.go")
return 2
}
k.go
package d
import "fmt"
var _ int64 = K()
func init() {
fmt.Println("init in K.go")
}
func K() int64 {
fmt.Println("calling K() in a.go")
return 2
}
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
}
main.go
package main
import (
"fmt"
"time"
"d"
)
var _ int64 = s()
func init() {
fmt.Println("init in sandbox.go")
}
func s() int64 {
fmt.Println("calling s() in sandbox.go")
return 2
}
func main() {
d.D()
fmt.Println("main")
time.Sleep(10000*time.Second)
}
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 2
}
那麼問題來了,當執行go build命令,控制檯能列印出什麼東西呢?順序又是怎麼的呢?
順序出來了。
- calling d() in a.go
- calling K() in a.go
- init in d.go
- init in K.go
- 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
- calling d() in a.go
- main
如果你對Go語言基礎掌握的不是很好,看到這個結果是很不理解的。
下面給出解釋。
包的初始化
要想使用匯入的包首先需要初始化它,這是由golang的執行系統完成的,主要包括(順序很重要):
- 初始化匯入的包(遞迴的定義)
- 在包級別為宣告的變數計算並分配初始值
- 執行包內的 init 函式(下面的空白識別符號就是一個例子)
- 不管包被匯入多少次,都只會被初始化一次。
順序
Go 的包中有很多的檔案,如果變數和函式在包的多個檔案當中,那麼變數的初始化和 init 函式的呼叫順序又是什麼樣的呢?首先,初始化依賴機制會啟動(更多 Go 中的初始化依賴)當初始化依賴機制完成的時候,就需要決定 a.go 和 z.go 中的初始化變數誰會被更早的處理,而這要取決於呈現給編譯器的檔案順序。如果 z.go 先被傳遞到構建系統,那麼變數的初始化就會比在 a.go 中先一步完成,這也同樣適用於 init 函式的觸發。Go 語言規範建議我們始終使用相同的順序傳遞,即按照詞法順序傳遞包中的檔名。
為了保證可重複的初始化行為,構建系統鼓勵按照詞法檔名的順序將屬於同一個包中的多個檔案呈現給編譯器。
相關文章
- Java中,類與類,類中的程式碼執行順序Java
- java類內部程式碼執行順序Java
- 【JavaScript】JS引擎中執行上下文如何順序執行程式碼JavaScriptJS行程
- JavaScript程式碼執行順序和資料型別JavaScript資料型別
- Java中建構函式、靜態程式碼塊、程式碼塊的執行順序Java函式
- Sql執行順序SQL
- Java中如何保證執行緒順序執行Java執行緒
- 總結類初始化時的程式碼執行順序
- pipeline的執行順序
- JavaScript執行順序分析JavaScript
- mySQL 執行語句執行順序MySql
- C#中Page執行順序:OnPreInit()、OnInit()……C#
- Java中構造方法,構造程式碼塊和靜態程式碼塊執行順序詳解Java構造方法
- Select語句執行順序
- Spring Aop的執行順序Spring
- sql mysql 執行順序 (4)MySql
- SQL語句執行順序SQL
- js執行順序Event LoopJSOOP
- mysql 中sql語句關鍵字的書寫順序與執行順序MySql
- go fiber: 多個全域性中介軟體的執行順序Go
- Java for迴圈中語句執行的順序Java
- Js中async/await的執行順序詳解JSAI
- 你是否真的懂 [程式的執行順序] 多程式 / 程式池
- 夯實Java基礎系列7:Java 程式碼塊和執行順序Java
- Pytest 順序執行,依賴執行,引數化執行
- mysql 語句的執行順序MySql
- [20191215]seq控制執行順序.txt
- 關於 Promise 的執行順序Promise
- sql select語法執行順序SQL
- SQL 語句的執行順序SQL
- async await、Promise、setTimeout執行順序AIPromise
- js解惑-函式執行順序JS函式
- nestJs中 Guards ,Interceptors ,Pipes ,Controller ,Filters的執行順序JSControllerFilter
- JS中的async/await的執行順序詳解JSAI
- 聊聊如何讓springboot攔截器的執行順序按我們想要的順序執行Spring Boot
- join、volatile、newSingleThreadLatch 實現執行緒順序執行thread執行緒
- 在繼承當中這些方法及程式碼塊執行順序是什麼樣的繼承
- Java普通程式碼塊,構造程式碼塊,靜態程式碼塊區別,執行順序的程式碼例項Java