1、 常量可以是全局常量,也可以是函數內部的局部常量。常量的值不可修改,常量表達式的值在編譯期計算,而不是在運行期。存儲在常量中的數據類型只可以是布爾型、數字型(整數型、浮點型和復數)和字符串型。當常量比較少時,推薦如下:
const 常量名1 = 常量值/常量表達式
const 常量名2 = 常量值/常量表達式
const pi = 3.14159
2、和變量聲明一樣,可以批量聲明多個常量,當常量較多時:推薦
const (
常量名1 【類型名稱1】= 常量值/常量表達式
常量名2 【類型名稱2】= 常量值/常量表達式
常量名3 【類型名稱3】= 常量值/常量表達式
)
其中數據類型可以省略,第一個常量必須給定一個確定的值,這里就是常量名1 。一般建議是每個都給定值,且一般也不用寫常量類型,除非有必要,也可以給部分常量賦值,第一個必須給定,其余的都可不給,沒給定的就取值為上一個顯示給定的值,還可以用iota來賦值。第一個常量賦值有:iota賦值/正常賦值。
iota的規則是:iota從0開始自增,從第一個表達式開始為0,依次遞增,后面的常量則是使用相同的表達式,只是iota的值不同而已。簡單地講,每遇到一次 const 關鍵字,iota 就重置為 0,且iota只能用在給常量賦值語句中。iota的值按照每走過一行(該行有常量才算)而自增。
const(
a = iota //a=0
b = iota + 5 //b=6
c //c=7 沿用了 iota + 5這個表達式
d //d=8
)
const(
a, b = iota, iota + 5 //a=0,b=5,這就要求緊接着下面行如果是沒有顯式賦值,則必須都是兩個常量,或者單獨賦值。對應賦值
c, d //c=1,d=6
e, f //e=2,f=7
g = iota //g=0
)
第一個聲明了常量類型,然后用iota初始化常量。


const ( a = iota b = iota c = iota )
const ( a = iota b c )
const ( Sunday = 1 << (iota + 1) Monday Tuesday Wednesday Thursday Friday Saturday )
type Color int const ( RED Color = iota // 0 ORANGE // 1 YELLOW // 2 GREEN // .. BLUE INDIGO VIOLET // 6 )
3、常量表達式:
常量間的所有算術運算、邏輯運算和比較運算的結果也是常量,對常量的類型轉換操作或以下函數調用都是返回常量結果:len、cap、real、imag、complex和unsafe.Sizeof(§13.1)。
4、無類型常量,只有常量可以是無類型的。。雖然一個常量可以有任意有一個確定的基礎類型,例如int或float64,或者是類似time.Duration這樣命名的基礎類型,但是許多常量並沒有一個明確的基礎類型。
編譯器為這些沒有明確的基礎類型的數字常量提供比基礎類型更高精度的算術運算;你可以認為至少有256bit的運算精度。
這里有六種未明確類型的常量類型,分別是:
無類型的布爾型: true,false
無類型的整數:
無類型的字符:
無類型的浮點數:
無類型的復數:
無類型的字符串:字符串面值常量是無類型的字符串類型
當一個無類型的常量被賦值給一個變量的時候,就像下面的第一行語句,或者出現在有明確類型的變量聲明的右邊,如下面的其余三行語句,無類型的常量將會被隱式轉換為對應的類型,如果轉換合法的話。
var f float64 = 3 + 0i // untyped complex -> float64 f = 2 // untyped integer -> float64 f = 1e123 // untyped floating-point -> float64 f = 'a' // untyped rune -> float64
上面的語句相當於:
var f float64 = float64(3 + 0i) f = float64(2) f = float64(1e123) f = float64('a')
無論是隱式或顯式轉換,將一種類型轉換為另一種類型都要求目標可以表示原始值。對於浮點數和復數,可能會有舍入處理:
const ( deadbeef = 0xdeadbeef // untyped int with value 3735928559 a = uint32(deadbeef) // uint32 with value 3735928559 b = float32(deadbeef) // float32 with value 3735928576 (rounded up) c = float64(deadbeef) // float64 with value 3735928559 (exact) d = int32(deadbeef) // compile error: constant overflows int32 e = float64(1e309) // compile error: constant overflows float64 f = uint(-1) // compile error: constant underflows uint )
對於一個沒有顯式類型的變量聲明(包括簡短變量聲明),常量的形式將隱式決定變量的默認類型,就像下面的例子:
i := 0 // untyped integer; implicit int(0) r := '\000' // untyped rune; implicit rune('\000') f := 0.0 // untyped floating-point; implicit float64(0.0) c := 0i // untyped complex; implicit complex128(0i)
注意有一點不同:無類型整數常量轉換為int,它的內存大小是不確定的,但是無類型浮點數和復數常量則轉換為內存大小明確的float64和complex128。 如果不知道整型類型的內存大小是很難寫出正確的數值算法的,因此Go語言不存在整型類似的不確定內存大小的浮點數和復數類型。
如果要給變量一個不同的類型,我們必須顯式地將無類型的常量轉化為所需的類型,或給聲明的變量指定明確的類型,像下面例子這樣:
var i = int8(0) var i int8 = 0
當嘗試將這些無類型的常量轉為一個接口值時(見第7章),這些默認類型將顯得尤為重要,因為要靠它們明確接口對應的動態類型。
fmt.Printf("%T\n", 0) // "int" fmt.Printf("%T\n", 0.0) // "float64" fmt.Printf("%T\n", 0i) // "complex128" fmt.Printf("%T\n", '\000') // "int32" (rune)