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