大家好,我是煎魚。
有一個讀者剛入門 Go ,提了一個很有意思的問題:Go 有幾種種宣告變數的方式,作為初學者,到底用哪種,有什麼區別,又為什麼要有多種宣告方式呢?
為此,煎魚將和大家一起探索這個問題。
變數宣告
在 Go 中,一共有 2 種變數宣告的方式,各有不同的使用場景。
分別是:
- 標準變數宣告(Variable declarations)。
- 簡短變數宣告(Short variable declarations)
標準宣告
變數宣告建立了一個或多個變數,為它們繫結了相應的識別符號,並給每個變數一個型別和初始值。
使用語法:
VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
案例程式碼:
var i int
var U, V, W float64
var k = 0
var x, y float32 = -1, -2
var (
i int
u, v, s = 1.0, 2.0, "腦子進煎魚了"
)
簡短宣告
一個短變數宣告。使用語法:
ShortVarDecl = IdentifierList ":=" ExpressionList .
案例程式碼:
s := "煎魚進腦子了"
i, j := 0, 10
f := func() int { return 7 }
ch := make(chan int)
r, w, _ := os.Pipe()
_, y, _ := coord(p)
網友疑惑
在我們群裡的 Go 讀者提了這問題後,我也搜了搜相關資料。發現在 stackoverflow 上也有人提出了類似的疑惑:
問題是:使用哪一種宣告方式,令人困惑。
題主糾結的原因在於:
- 如果一個只是另一個的速記方式,為什麼它們的行為會不同?
- Go 的作者出於什麼考慮,讓兩種方式來宣告一個變數(為什麼不把它們合併成一種方式)?只是為了迷惑我們?
- 有沒有其他方面需要我在使用時留心的,以防掉進坑裡?
下面我們結合 stackoverflow 的這個提問內容和回答,進一步展開。
思考一下:標準宣告和短宣告,這兩者的區別的在哪那裡,又或是憑喜好隨意使用?
區別在哪
程式碼塊的分組宣告
使用包含關鍵字 var 的宣告語法時,和其他 package、import、const、type、var 等關鍵字一樣,是可以進行分組的程式碼塊宣告的。
例如:
var (
i int
u, v, s = 1.0, 2.0, "腦子進煎魚了"
)
而短宣告,是不支援的。
變數的初始值指定
使用標準的變數定義時,我們可以只宣告,不主動地定義該變數的初始值(預設會給零值)。
例如:
var (
i int
s string
)
而短宣告則不行,必須要在程式中主動地去對變數定義一個值。
例如:
s := "腦子進煎魚了"
此處即使是定義的空字串,那也屬於是使用者側主動定義的,而非預設的零值。
區域性變數,區分作用域
在編寫程式時,我們經常會有一些區域性變數宣告,且作用域是有限的。
可以看看自己的程式碼,這種時候,我們都會採取短宣告的方式。
例如:
for idx, value := range array {
// Do something with index and value
}
if num := runtime.NumCPU(); num > 1 {
fmt.Println("Multicore CPU, cores:", num)
}
短宣告在這類場景下有明確的優勢,標準的變數宣告在這類場景不討好。
重新宣告變數
在 Go 語言規範中有明確提到,短變數宣告是可以重新宣告變數的,這是一個高頻重新宣告的覆蓋動作。
如下:
var name = "煎魚.txt"
fi, err := os.Stat(name)
if err != nil {
log.Fatal(err)
}
data, err := ioutil.ReadFile(name)
if err != nil {
log.Fatal(err)
}
...
上述程式碼中,err 變數就是不斷地被反覆定義。在 if err != nil
猖狂的現在,短變數在此處的優勢,簡直是大殺器了。
總結
相信很多小夥伴初入門時都為此糾結過一下,又或是很多教程壓根就沒有說清楚兩者變數宣告的區別。
在今天這篇文章中,我們介紹了 Go 的兩種變數宣告放水。並且針對短宣告存在的場景進行了說明。
主要是:
- 程式碼塊的分組宣告。
- 變數的初始值指定。
- 區域性變數,區分作用域。
- 重新宣告變數。
你覺得變數宣告上,還有沒有別的優缺點呢,歡迎在評論區交流:)
若有任何疑問歡迎評論區反饋和交流,最好的關係是互相成就,各位的點贊就是煎魚創作的最大動力,感謝支援。
文章持續更新,可以微信搜【腦子進煎魚了】閱讀,本文 GitHub github.com/eddycjy/blog 已收錄,學習 Go 語言可以看 Go 學習地圖和路線,歡迎 Star 催更。