Go 語言的變量與常量
變量
go 語言的變量聲明和大多數(shù)語言類似,通過 var 關(guān)鍵字聲明變量,只是 go 語言作為靜態(tài)類型語言,聲明變量時需要指定其類型。
下面的代碼表示聲明一個『name』變量,類型為『string』,并給其賦值『"Shenfq"』。
- var name string = "Shenfq"
如果我們不進行賦值,這變量會獲得一個默認(rèn)值,下面列舉一些 go 語言中的基礎(chǔ)類型及其默認(rèn)值。
多變量聲明
上面介紹 go 語言通過 var 關(guān)鍵字進行單個變量聲明,我們還可以通過 var 關(guān)鍵字進行多個變量的聲明:
- // 聲明兩個變量為同一類型
- var firstName, lastName string
- // 給兩個變量同時賦值
- firstName, lastName = "frank", "shen"
- // 聲明兩個變量為不同類型
- var (
- age int
- name string
- )
- // 給兩個變量同時賦值
- age, name = 25, "Shenfq"
類型推導(dǎo)
如果我們在變量聲明階段,對變量進行了賦值操作,這時候我們是可以直接省略變量類型的,因為 go 在編譯過程中會依據(jù)所賦予的初始值推導(dǎo)出其類型。
- var age = 25
- fmt.Printf("age 類型為:%T", age) // age 類型為:int
- var (
- age = 18
- name = "Shenfq"
- )
- fmt.Printf("age 類型為:%T", age) // age 類型為:int
- fmt.Printf("name 類型為:%T", name) // name 類型為:string
簡短格式
前面介紹了變量聲明的時候,如果給定了初始值,go 在編譯階段可以進行類型推導(dǎo)。這種情況,go 提供了一種更簡單的聲明方式,通過 := 的方式進行變量聲明,可以省略 var 關(guān)鍵字。
- func main() {
- age := 25
- name := "Shenfq"
- }
- // 也可以進行多個變量同時賦值
- func main() {
- age, name := 25, "Shenfq"
- }
⚠️注意事項一
這種聲明方式只能用于函數(shù)體內(nèi),不能用于全局變量的聲明。
- // ⚠️ 不能在全局使用這種方式聲明變量
- age, name := 25, "Shenfq"
- // 只能在函數(shù)體內(nèi)使用該方式
- func main() {
- age, name := 25, "Shenfq"
- fmt.Printf("age 類型為:%T", age)
- fmt.Printf("name 類型為:%T", name)
- }
warning
⚠️注意事項二
已經(jīng)聲明過的變量,不能使用 := 的方式進行賦值。
- func main() {
- var age int
- age := 25
- }
已經(jīng)聲明過的變量,只能通過 = 的方式進行賦值。
- func main() {
- var age int
- age = 25
- }
全局變量與局部變量
簡單來說,聲明在函數(shù)體外的變量為全局變量,聲明在函數(shù)體內(nèi)的變量為局部變量。
局部變量如果有聲明,沒有進行使用,則不會通過編譯。
- func main() {
- var age int
- }
但是,全局變量是可以聲明而不使用的。
- var age int
- func main() {
- name := "Shenfq"
- //fmt.Printf("age 類型為:%T", age)
- fmt.Printf("name 類型為:%T", name)
- }
上面的代碼中,我們聲明了 age 全局變量,但是并未使用,可以正常編譯。
空白標(biāo)識符
前面介紹過,go 在變量賦值的時候,可以一次性對多個變量賦值。同時,go 的函數(shù)在 return 的時候,也能一次返回多個結(jié)果。
- func double(num int) (string, int) {
- var err string
- if num < 0 {
- err = "num 不能為負(fù)數(shù)"
- return err, -1
- }
- result := num * 2
- return err, result
- }
上面我們實現(xiàn)了一個 double 函數(shù),該函數(shù)接受一個 int 類型的變量(num),返回兩個值,一個為異常提示(string 類型),一個為 num * 2 的結(jié)果。如果 num < 0 , 則提示 num 不能負(fù)數(shù)。
- func main() {
- err, res := double(10)
- if err != "" {
- fmt.Printf(err)
- } else {
- fmt.Printf("結(jié)果為:%v", res)
- }
- }
如果,我們并不關(guān)心 err ,只想執(zhí)行 double 之后,輸出其結(jié)果。
- func main() {
- err, res := double(10)
- fmt.Printf("結(jié)果為:%v", res)
- }
運行后,我們會收到一個編譯錯誤,err 變量并未使用。這時候,就需要用到空白標(biāo)識符(_)。
- func main() {
- _, res := double(10)
- fmt.Printf("結(jié)果為:%v", res)
- }
我們可以通過 _ 來接受 err 值,這個地方的值就會被拋棄掉,就能順利通過編譯。
常量
常量就是不會發(fā)生變化的變量,一旦聲明就不會改變。go 語言中,常量的聲明只需要將變量聲明時的 var 關(guān)鍵字替換為 const 關(guān)鍵字。
- // 隱式類型定義
- const PI = 3.14
- // 顯式類型定義
- const PI2 float = 3.14
多常量聲明
與變量類似,常量也支持一次性聲明多個。
- func main() {
- const (
- PI = 3.14
- PI2 = 3.14
- )
- fmt.Printf("結(jié)果為:%v\n", PI)
- fmt.Printf("結(jié)果為:%v\n", PI2)
- }
如果一次聲明多個常量時,某個常量如果為進行賦值,默認(rèn)會與上一個常量的值進行同步。下面代碼的運行結(jié)果,與上面的代碼一致。
- func main() {
- const (
- PI = 3.14
- PI2
- )
- fmt.Printf("結(jié)果為:%v\n", PI)
- fmt.Printf("結(jié)果為:%v\n", PI2)
- }
特殊常量
有個叫做 iota 的特殊常量,在常量的賦值過程中,會進行累加。
- func main() {
- const (
- A = iota
- B
- C
- )
- fmt.Println(A, B, C) // 0 1 2
- }
在 iota 累加的過程中,可以對其進行打斷。
- func main() {
- const (
- A = iota
- B
- C = "Shenfq"
- D
- E
- )
- fmt.Println(A, B, C, D, E)
- }
這時候輸出的結(jié)果為:
這是由于我們將常量 C 修改為了字符串 "Shenfq",常量 D、E 會默認(rèn)與上一條常量保持同步,所以會得到上述結(jié)果。但是, iota 是支持重新恢復(fù)累加,只需要在指定位置重新賦值一次 iota 即可。
- func main() {
- const (
- A = iota
- B
- C = "Shenfq"
- D = iota // 恢復(fù)累加狀態(tài)
- E
- )
- fmt.Println(A, B, C, D, E)
- }
由于 C 占用了原本 2 的位置,所以 D 恢復(fù)后,也是從 3 開始的。
iota 這種累加的特性,特別像我們在其他語言中使用的枚舉,所以在 go 語言中,我們可以直接將 iota 當(dāng)做枚舉來使用。
- type ButtonType int
- const (
- Default ButtonType = iota
- Primary
- Warning
- Error
- )