簡介
道可道,非常道。這裡常道指的永恆不變的道理,常有不變的意思。顧名思義和變數相比,常量在宣告之後就不可改變,它的值是在編譯期間就確定的。
下面簡單的宣告一個常量:
const p int = 1
宣告常量的時候可以指定型別也可以類似:=
簡單宣告一樣,不指定型別如下:
const p = 1
也可以同時給多個賦值:
const i, j = 1, 2
const m, n = 1, "a"
也可以批量的宣告:
const (
a = 0
b = 1
)
如果批量的宣告,後面的可以省略宣告具體的值,它會和上一行的值保持一致比如:
const (
a = 1
b
c = 2
d
)
fmt.Println(a, b, c, d) // "1 1 2 2"
無型別常量
我們曾多次提到Go
是一門靜態語言,變數的型別是不可變,甚至不可以對int
和int32
兩種型別的變數進行+
操作,即使int
也是32
位的例如:
package main
import "fmt"
func main() {
var a int = 1
var b int32 = 2
fmt.Println(a + b)
}
編譯的時候會報invalid operation: a + b (mismatched types int and int32)
而簡單宣告的變數又是什麼型別呢把上面的程式碼修改
package main
import "fmt"
func main() {
a := 1
var b int = 2
fmt.Println(a + b)
}
發現是可以執行的,但是如果把b
改成var b int32 = 2
也會報相同的錯誤,說明:=
會給變數指定一個預設的資料型別,這個型別是確定。
常量和變數有一個很大的不同就是,它對六種基礎資料型別 布林、整數、字元、浮點數、複數、字串
,如果宣告的時候沒有明確指定型別,它是不確定型別
的,而是用到它的時候再確定它是否滿足這個型別的執行去確定它具體的型別。回到上面的程式碼,我們如果改成這樣:
package main
import "fmt"
func main() {
const a = 1
var b int32 = 2
fmt.Println(a + b)
}
這時執行通過,執行的時候a
是 int32型別。那麼是不是它以後一直是這一種型別呢,我們看看下面的程式碼:
package main
import "fmt"
func main() {
const a = 1
var b int32 = a
var c int = a
fmt.Println(a)
fmt.Println(c)
}
我們可以看到c
和b
不是相同型別,但還是可以把a
即賦值給b
也可以賦值給c
。也就是說只要是整數,不論是什麼型別都可以參與執行。同樣的道理,只要宣告常量的時候沒有指定型別,給它的賦值又是六種基本型別,常量都可以滿足這個特性。
特殊常量iota
iota
可以理解為一個特殊的常量,它只能和const
一起出現,而且只要const
出現它就會被重置為0
,然後每有一個常量被宣告它就加1
package main
import "fmt"
func main() {
const (
a = iota
b
c
)
println(a, b, c) // 0 1 2
const (
d = iota
e
f
)
fmt.Println(d, e, f) // 0 1 2
}
上面的a, b, c
的宣告從0開始,每增加一行就加1。到d, e, f
之後由於出現了const
所以iota
又被重置為0
了。
iota
也可以在宣告中參加運算,例如
const (
a = iota * 3
b
c
)
fmt.Println(a, b, c) // 0 3 6
下面一行保持和第一行相同的執行規則只是iota
加1
了,所以相當於b = 3 * 1