常量
- 相對于變量,常量是恒定不變的值,多用于定義程序運行期間不會改變的值,存放于內(nèi)存的數(shù)據(jù)區(qū)。
- 常量可用于將特殊的值進行語義化,使用時根據(jù)名稱可知道具體含義。
- 常量可將數(shù)據(jù)集中管理,只要更改常量定義即可完成全部的修改。
- 常量可保證不被程序的其它代碼更改
字面常量
- 字面常量(literal)是指程序中硬編碼的常量
- Golang的字面常量更接近于自然語言中的常量的概念,是無類型的。
const pi = 3.14159
const e = 2.7182
常量定義
- 常量聲明與變量聲明類似,只是將
var換成const。 - 常量是簡單值的標識符,值類型只能是布爾型、數(shù)字型、字符串型。
- 常量定義時必須賦值,且不能多次賦值。
const identifier [type] = value
類型推導(dǎo)
- 常量定義可以限定其類型但并非必須,若定義常量時沒有指定類型則與字面常量一樣,是無類型常量。
- 常量類型可通過值推導(dǎo)出來,大多數(shù)情況可省略類型。
const (
PI float64 = 3.1415926
zero = 0.0
size int64 = 1024
eof = -1
)
- 常量不能使用短語法
:=來定義
const defaultMaxIdleConns = 2
const minReadBufferSize = 16
const maxConsecutiveEmptyReads = 100
常量賦值
常量是在編譯時確定,因此不能使用變量為其賦值??墒褂么_定的字面量、字面量運算、內(nèi)置函數(shù)運算、其他定義的常量,這些在編譯時可以確定地內(nèi)容為其賦值。
- 常量定義的右值可以是一個在編譯期運算的常量表達式
const (
_ = iota
KB = 1 << (10 * iota) //2^10
MB = 1 << (10 * iota)//2^20
GB = 1 << (10 * iota)//2^30
TB = 1 << (10 * iota)//2^40
PB = 1 << (10 * iota)//2^50
)
fmt.Println(KB, MB, GB, TB, PB) //1024 1048576 1073741824 1099511627776 1125899906842624
- 由于常量的賦值是一個編譯器行為,因此右值不能出現(xiàn)任何需要運行期才能得出結(jié)果的表達式。
const mask = 1 << 3
fmt.Println(mask) //8
- 常量可使用
len()、cap()、unsafe.Sizeof()函數(shù)計算表達式的值 - 常量表達式中函數(shù)必須是內(nèi)置函數(shù),否則編譯失敗。
const (
noDelay time.Duration = 0
timeout = time.Minute * 10
)
由于常量的運算是在編譯期完成的,這樣不僅可以減少運行時的工作,也方便其他代碼的編譯優(yōu)化。當(dāng)操作數(shù)是常量時,一些運行時的錯誤可以在編譯時被發(fā)現(xiàn),比如整數(shù)除零、字符串索引越界、任何導(dǎo)致無效浮點數(shù)的操作等。
批量定義
- 使用
const()定義塊可一次性定義多個常量,每個常量獨占一行。
const (
IPv4Len = 4
IPv6Len = 6
)
const (
statusOK = 200
notFound = 404
)
-
const()塊定義時,若常量未給出定義則會延續(xù)上面的定義規(guī)則。
const (
ErrorCode = 0
FailCode
)
log.Println(FailCode) //0
預(yù)定義常量
- Golang預(yù)定的常量包括
true、false、iota
常量生成器
-
iota比較特殊,可認為是一個可被編譯器修改的常量。 - 若兩個
const賦值語句的表達式一樣則可省略后一個賦值表達式
type Gender int
const (
Secret Gender = iota
Male
Famale
)
log.Println(Famel) //2
-
const配置itoa關(guān)鍵字可定義一組由0開始加1迭代的常量
const (
c1 = iota
c2 = 100
c3 = iota
c4
)
fmt.Println(c1, c2, c3, c4) //0 100 2 3
-
iota在const關(guān)鍵字出現(xiàn)時會被重置為0 -
const中每新增一行常量聲明會使iota計數(shù)一次(自增1),因此iota可視為const語句塊中的索引行。
const (
c1, c2 = iota + 1, iota + 2
c3, c4 = iota + 3, iota + 4
)
fmt.Println(c1, c2, c3, c4) //1 2 4 5
枚舉
- 枚舉是指一系列相關(guān)的常量
- Golang并不支持眾多其它語言明確支持的
enum枚舉關(guān)鍵字,常量可做枚舉使用。
type CompressionLevel int
const (
DefaultCompression CompressionLevel = 0
NotCompression CompressionLevel = -1
BestSpeed CompressionLevel = -2
BestCompression CompressionLevel = -3
)
作用域
- 常量可作為全局常量使用,也可在函數(shù)內(nèi)部作為局部常量使用。
- Golang中標識符是否大小寫,取決于是否需要在導(dǎo)出時被識別。
- 與Golang其他符號一樣,以大寫字母開頭的常量在包外可見,小寫字母開頭的常量在包外不可見。
type Weekday int
const (
Sunday Weekday = iota
Mondy
Tuesday
Thursday
Friday
Saturday
numbeOfWeekdays
)
無類型常量
Golang中常量有個不同尋常之處,雖然常量可以具有任意的基礎(chǔ)類型,但許多常量并沒有一個明確的基礎(chǔ)類型。編譯器為這些沒有明確類型的數(shù)字常量提供了比基礎(chǔ)類型更高精度的算術(shù)運算,至少有256bit的運算精度。
通過延遲明確常量的具體類型,不僅可以提供更高的運算精度,還可以直接用于更多的表達式而非顯式的類型轉(zhuǎn)換。
const (
pi32 float32 = math.Pi
pi64 float64 = math.Pi
pi128 complex128 = math.Pi
)