定義
關(guān)鍵字 const
被用于表示常量统阿,常量用于存儲(chǔ)不會(huì)改變的數(shù)據(jù),常量中的數(shù)據(jù)類型只可以是布爾型筹我、數(shù)字型(整數(shù)型扶平、浮點(diǎn)型和復(fù)數(shù))和字符串型。
const identifier [type] = value
常量不能再重新賦值為其他的值
const a = 55 // 允許
a = 89 // 不允許重新賦值
常量的值會(huì)在編譯的時(shí)候確定蔬蕊。因?yàn)楹瘮?shù)調(diào)用發(fā)生在運(yùn)行時(shí)结澄,所以不能將函數(shù)的返回值賦值給常量。
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Hello, playground")
var a = math.Sqrt(4) // 允許
const b = math.Sqrt(4) // 不允許
}
在上面的程序中岸夯,因?yàn)?a
是變量麻献,因此我們可以將函數(shù) math.Sqrt(4)
的返回值賦值給它(我們將在單獨(dú)的地方詳細(xì)討論函數(shù))。
b
是一個(gè)常量猜扮,它的值需要在編譯的時(shí)候就確定勉吻。函數(shù) math.Sqrt(4)
只會(huì)在運(yùn)行的時(shí)候計(jì)算,因此 const b = math.Sqrt(4)
將會(huì)拋出錯(cuò)誤 error main.go:11: const initializer math.Sqrt(4) is not a constant)
字符串常量
??雙引號(hào)中的任何值都是 Go 中的字符串常量旅赢。例如像 Hello World
或 Sam
等字符串在 Go 中都是常量齿桃。
什么類型的字符串屬于常量?答案是他們是無類型的煮盼。
像 Hello World
這樣的字符串常量沒有任何類型短纵。
const hello = "Hello World"
上面的例子,我們把 Hello World
分配給常量 hello
〗┛兀現(xiàn)在常量 hello
有類型嗎香到?答案是沒有。常量仍然沒有類型报破。Go 是一門強(qiáng)類型語言悠就,所有的變量必須有明確的類型。那么, 下面的程序是如何將無類型的常量 Sam
賦值給變量 name
的呢充易?
package main
import (
"fmt"
)
func main() {
var name = "Sam"
fmt.Printf("type %T value %v", name, name)
}
答案是無類型的常量有一個(gè)與它們相關(guān)聯(lián)的默認(rèn)類型理卑,并且當(dāng)且僅當(dāng)一行代碼需要時(shí)才提供它。在聲明中 var name = "Sam"
蔽氨, name
需要一個(gè)類型藐唠,它從字符串常量 Sam
的默認(rèn)類型中獲取帆疟。**
有沒有辦法創(chuàng)建一個(gè)帶類型的常量?答案是可以的宇立。以下代碼創(chuàng)建一個(gè)有類型常量踪宠。
const typedhello string = "Hello World"
上面代碼中, typedhello
就是一個(gè) string
類型的常量妈嘹。
Go 是一個(gè)強(qiáng)類型的語言柳琢,在分配過程中混合類型是不允許的。讓我們通過以下程序看看這句話是什么意思润脸。
package main
func main() {
var defaultName = "Sam" // 允許
type myString string
var customName myString = "Sam" // 允許
customName = defaultName // 不允許
}
在上面的代碼中柬脸,我們首先創(chuàng)建一個(gè)變量 defaultName
并分配一個(gè)常量 Sam
。常量 Sam
的默認(rèn)類型是 string
毙驯,所以在賦值后defaultName
是 string
類型的倒堕。
下一行矛物,我們將創(chuàng)建一個(gè)新類型 myString
漱挚,它是 string
的別名娩践。
然后我們創(chuàng)建一個(gè) myString
的變量 customName
并且給他賦值一個(gè)常量 Sam
瘩例。因?yàn)槌A?Sam
是無類型的详幽,它可以分配給任何字符串變量畜份。因此這個(gè)賦值是允許的隅很,customName
的類型是 myString
寄症。
現(xiàn)在序愚,我們有一個(gè)類型為 string
的變量 defaultName
和另一個(gè)類型為 myString
的變量 customName
憔披。即使我們知道這個(gè) myString
是 string
類型的別名。Go 的類型策略不允許將一種類型的變量賦值給另一種類型的變量爸吮。因此將 defaultName
賦值給 customName
是不允許的活逆,編譯器會(huì)拋出一個(gè)錯(cuò)誤 main.go:7:20: cannot use defaultName (type string) as type myString in assignmen
。
布爾常量
布爾常量和字符串常量沒有什么不同拗胜。他們是兩個(gè)無類型的常量 true
和 false
蔗候。字符串常量的規(guī)則適用于布爾常量,所以在這里我們不再重復(fù)埂软。以下是解釋布爾常量的簡單程序锈遥。
package main
func main() {
const trueConst = true
type myBool bool
var defaultBool = trueConst // 允許
var customBool myBool = trueConst // 允許
defaultBool = customBool // 不允許
}
上面的程序是自我解釋的。
數(shù)字常量
數(shù)字常量包含整數(shù)勘畔、浮點(diǎn)數(shù)和復(fù)數(shù)的常量所灸。數(shù)字常量中有一些微妙之處。
讓我們看一些例子來說清楚炫七。
package main
import (
"fmt"
)
func main() {
const a = 5
var intVar int = a
var int32Var int32 = a
var float64Var float64 = a
var complex64Var complex64 = a
fmt.Println("intVar",intVar, "\nint32Var", int32Var, "\nfloat64Var", float64Var, "\ncomplex64Var",complex64Var)
}
上面的程序爬立,常量 a
是沒有類型的,它的值是 5
万哪。您可能想知道 a
的默認(rèn)類型是什么侠驯,如果它確實(shí)有一個(gè)的話, 那么我們?nèi)绾螌⑺峙浣o不同類型的變量抡秆。答案在于 a
的語法。下面的程序?qū)⑹故虑楦忧逦?/p>
package main
import (
"fmt"
)
func main() {
var i = 5
var f = 5.6
var c = 5 + 6i
fmt.Printf("i's type %T, f's type %T, c's type %T", i, f, c)
}
在上面的程序中吟策,每個(gè)變量的類型由數(shù)字常量的語法決定儒士。5
在語法中是整數(shù), 5.6
是浮點(diǎn)數(shù)檩坚,5+6i
的語法是復(fù)數(shù)着撩。當(dāng)我們運(yùn)行上面的程序,它會(huì)打印出 i's type int, f's type float64, c's type complex128
匾委。
現(xiàn)在我希望下面的程序能夠正確的工作拖叙。
package main
import (
"fmt"
)
func main() {
const a = 5
var intVar int = a
var int32Var int32 = a
var float64Var float64 = a
var complex64Var complex64 = a
fmt.Println("intVar",intVar, "\nint32Var", int32Var, "\nfloat64Var", float64Var, "\ncomplex64Var",complex64Var)
}
在這個(gè)程序中, a
的值是 5
赂乐,a
的語法是通用的(它可以代表一個(gè)浮點(diǎn)數(shù)薯鳍、整數(shù)甚至是一個(gè)沒有虛部的復(fù)數(shù)),因此可以將其分配給任何兼容的類型沪猴。這些常量的默認(rèn)類型可以被認(rèn)為是根據(jù)上下文在運(yùn)行中生成的。 var intVar int = a
要求 a
是 int
采章,所以它變成一個(gè) int
常量运嗜。 var complex64Var complex64 = a
要求 a
是 complex64
,因此它變成一個(gè)復(fù)數(shù)類型悯舟。很簡單的:)担租。
枚舉
常量還可以用作枚舉, 如下數(shù)字 0、1 和 2 分別代表未知性別抵怎、女性和男性
const (
Unknown = 0
Female = 1
Male = 2
)
關(guān)鍵字iota奋救,這個(gè)關(guān)鍵字用來聲明enum的時(shí)候采用,它默認(rèn)開始值是0反惕,const中每增加一行加1:
const (
x = iota // x == 0
y // y == 1
z // z == 2
w //w ==3
)
func main() {
fmt.Println(x,y,z,w)
}
位運(yùn)算方式
const (
Open = 1 << iota //1
Close //2
Pending //4
)