天天看點

Go語言的常量與變量使用注意事項

一、變量

Go是靜态類型,不能在運作期改變變量的類型。

面試題

關于全局變量的初始化,下面正确的使用方式是
 A、var i int = 
 B、var i = 
 C、i := 
           

這是一個關于Go語言全局變量聲明和指派的考察,Go語言中的變量聲明使用關鍵字var,例如:

var str string    //聲明變量
str = "test"      //給變量指派
           

這邊var是定義變量的關鍵字,str是變量名稱,string是變量類型,=是指派符号,”test”是值。上面的程式分兩步,第一步聲明變量,第二步給變量指派。也可以将兩步合到一起。

使用關鍵字 var 定義變量,自動初始化為零值。如果提供初始化值,可省略變量類型,由編譯器自動推斷:

Go語言還提供了一種更簡短的寫法:

相當于先執行了var str string定義了str變量,再執行str = “test”的指派操作。

Go語言全局變量不支援在函數外進行指派,如:

var str string  //定義了一個全局變量str
str = "test"    //全局變量不支援這種操作
           

是以,全局變量不支援 str := “test”操作,此方法隻支援局部變量操作。

func main() {
    x :=  // 注意檢查,是定義新局部變量,還是修改全局變量。該⽅  >方式容易造成錯誤。
}
           

可一次定義多個變量:

var x, y, z int
var s, n = "abc",
var (
    a int
    b float32
)
func main() {
    i, s :=, "Hello, World!"
    println(x, s, n)
}
           

多變量指派時,先計算所有相關值,然後再從左到右依次指派。

data, i := [3]int{0, 1, 2}, 0
i, data[i] = 2, 100 // (i = 0) -> (i = 2), (data[0] = 100)
           

全局變量還支援若某個變量需要依賴其它變量,則被依賴的變量先初始化

var test1 = test2
var test2 = "test2"
           

二、常量

常量值必須是編譯期可确定的數字、字元串、布爾值。

const x, y int = ,  // 多常量初始化
const s = "Hello, World!" // 類型推斷
const ( // 常量組
    a, b = , 
    c bool = false
)
           

Go語言中當定義一個局部變量未使用會編譯錯誤,但是局部常量未使用不會引發編譯錯誤。

在常量組中,如不提供類型和初始化值,那麼視作與上一常量值相同。

const (
     s = "abc"
     x           // x = "abc"
)
           

常量值還可以是 len、cap、unsafe.Sizeof 等編譯期可确定結果的函數傳回值。

const (
 a = "abc"
 b = len(a)
 c = unsafe.Sizeof(b)
)
           

如果常量類型足以存儲初始化值,那麼不會引發溢出錯誤。

const (
    a byte =  // int to byte
    b int =  // float64 to int, overflows
)
           

面試題:

對于常量定義zero(const zero = 0.0),zero是浮點型常量,這一說話時候正确。(false)

Go語言常量有個不同尋常的地方,雖然一個常量可以有任意一個确定的類型,例如int或float64,但是很多常量卻并沒有一個明确的基礎類型,編譯器為這些沒有明确的基礎類型的數字變量提供了比基礎類型更高的算術運算。有六種未明确類型的變量類型,分别是無類型的布爾型,無類型的整數,無類型的字元,無類型的浮點數,無類型的複數,無類型的字元串。

枚舉

關鍵字 iota 定義常量組中從 0 開始按行計數的自增枚舉值。

const (
    Sunday = iota // 0
    Monday // 1,通常省略後續⾏行表達式。
    Tuesday // 2
    Wednesday // 3
    Thursday // 4
    Friday // 5
    Saturday // 6
)
           
const (
    _ = iota // iota = 0
    KB int64 = <<  * iota) // iota = 1
    MB // 與 KB 表達式相同,但 iota = 2
    GB
    TB
 )
           

MB,GB,TB會表達式與KB相同,都為1<<(10 * _),但是iota會自增

同樣的道理:

const (
    i <<iota //
    j<<iota
    k
    l
 )
           

i = 1,j=6,k=12,I=24。

iota每出現一次,自動加1;而前面的操作數如果不指定,預設使用上一個的,在這裡是3。則k=3<<2,I=3<<3。

如果 iota ⾃自增被打斷,須顯式恢複。

const (
    A = iota // 0
    B // 1
    C = "c" // c
    D // c,與上⼀一⾏行相同。
    E = iota // 4,顯式恢複。注意計數包含了 C、D 兩⾏行。
    F // 5
)
           
需要注意的是E=4,顯式恢複。