Skip to content

Go常量

常量的值無法在運行時改變,一旦賦值過後就無法修改,其值只能來源於:

  • 字面量
  • 其他常量標識符
  • 常量表達式
  • 結果是常量的類型轉換
  • iota

常量只能是基本數據類型,不能是

  • 除基本類型以外的其它類型,如結構體,接口,切片,數組等
  • 函數的返回值

常量的值無法被修改,否則無法通過編譯

初始化

常量的聲明需要用到const關鍵字,常量在聲明時就必須初始化一個值,並且常量的類型可以省略,例如

go
const name string = "Jack" // 字面量

const msg = "hello world" // 字面量

const num = 1 // 字面量

const numExpression = (1+2+3) / 2 % 100 + num // 常量表達式

如果僅僅只是聲明而不指定值,將會無法通過編譯

go
const name string

編譯器報錯

missing init expr for name

批量聲明常量可以用()括起來以提升可讀性,可以存在多個()達到分組的效果。

go
const (
   Count = 1
   Name  = "Jack"
)

const (
   Size = 16
   Len  = 25
)

在同一個常量分組中,在已經賦值的常量後面的常量可以不用賦值,其值默認就是前一個的值,比如

go
const (
  A = 1
  B // 1
  C // 1
  D // 1
  E // 1
)

iota

iota是一個內置的常量標識符,通常用於表示一個常量聲明中的無類型整數序數,一般都是在括號中使用。

go
const iota = 0

看幾個使用案例

go
const (
   Num = iota // 0
   Num1 // 1
   Num2 // 2
   Num3 // 3
   Num4 // 4
)

也可以這麼寫

go
const (
   Num = iota*2 // 0
   Num1 // 2
   Num2 // 4
   Num3 // 6
   Num4 // 8
)

還可以

go
const (
   Num = iota << 2*3 + 1 // 1
   Num1 // 13
   Num2 // 25
   Num3 = iota // 3
   Num4 // 4
)

通過上面幾個例子可以發現,iota是遞增的,第一個常量使用iota值的表達式,根據序號值的變化會自動的賦值給後續的常量,直到用新的const重置,這個序號其實就是代碼的相對行號,是相對於當前分組的起始行號,看下面的例子

go
const (
  Num  = iota<<2*3 + 1 // 1 第一行
  Num2 = iota<<2*3 + 1 // 13 第二行
  _ // 25 第三行
  Num3 //37 第四行
  Num4 = iota // 4 第五行
  _ // 5 第六行
  Num5 // 6 第七行
)

例子中使用了匿名標識符_佔了一行的位置,可以看到iota的值本質上就是iota所在行相對於當前const分組的第一行的差值。而不同的const分組則相互不會影響。

枚舉

Go 語言沒有為枚舉單獨設計一個數據類型,不像其它語言通常會有一個enum來表示。一般在 Go 中,都是通過自定義類型 + const + iota 來實現枚舉,下面是一個簡單的例子

go
type Season uint8

const (
  Spring Season = iota
  Summer
  Autumn
  Winter
)

這些枚舉實際上就是數字,Go 也不支持直接將其轉換為字符串,但我們可以通過給自定義類型添加方法來返回其字符串表現形式,實現Stringer接口即可。

go
func (s Season) String() string {
  switch s {
  case Spring:
    return "spring"
  case Summer:
    return "summer"
  case Autumn:
    return "autumn"
  case Winter:
    return "winter"
  }
  return ""
}

這樣一來就是一個簡單的枚舉實現了。你也可以通過官方工具Stringer來自動生成枚舉。

不過它有以下缺點:

  • 類型不安全,因為Season是自定義類型,可以通過強制類型轉換將其他數字也轉換成該類型

    go
    Season(6)
  • 繁瑣,字符串表現形式需要自己實現

  • 表達能力弱,因為const僅支持基本數據類型,所以這些枚舉值也只能用字符串和數字來進行表示

為什麼不在語言層面支持枚舉是筆者非常不能理解的一件事,我認為這絕對是利大於弊的。

Golang學習網由www.golangdev.cn整理維護