常量包含不會發生更改的數據。常量的數據類型只能是boolean、number(int/float/complex)或string。html
定義方式:數據結構
const NAME [TYPE] = VALUE
TYPE基本能夠省略,由於常量都是簡單數據類型,編譯器能夠根據值推斷出它的數據類型。閉包
例如:ide
const Pi = 3.14159
常量在編譯期間被評估,所以定義的常量必須是在編譯期間就能計算出來的結果。例如調用一些運行期間的函數來生成常量的值就是錯誤的,由於在編譯期間沒法調用這些運行期間的函數。常量的值定義好後,沒法在運行期間更改,不然會報錯。函數
const c = 3+2 // 正確 const d = getNumber() // 錯誤
常量的精度能夠隨意長,Go不會出現精度溢出的問題。且常量賦值時,若是值太長,可使用續行符\
:ui
const Ln2= 0.693147180559945309417232121458\ 176568075500134360255254120680009 const Log2E= 1/Ln2 const Billion = 1e9
Go中只有將超出變量精度的值賦值給變量時纔會出現溢出問題。code
能夠一次性定義多個常量:htm
const beef, two, c = "meat", 2, "veg" const Monday, Tuesday, Wednesday = 1, 2, 3 const ( Monday, Tuesday, Wednesday = 1, 2, 3 Thursday, Friday, Saturday = 4, 5, 6 )
常量能夠用枚舉。定義了下面的常量後,Female就表明了數值1。blog
const ( Unknown = 0 Female = 1 Male = 2 )
可使用iota
實現枚舉,iota
自身是builtin包中定義的一個常量,其值爲0,它用於在常量中定義序列數,從0開始增長:ip
const ( a = iota b = iota c = iota )
當iota
第一次調用時,產生數值0,在新行中再次調用iota,將自動增長1,因此上面的a=0,b=1,c=2
。上面的常量枚舉能夠簡寫成等價形式:
const ( a = iota b c )
iota不能用於運行期間,由於它是小寫字母開頭的常量,不會被導出。下面的代碼會報錯:iota未定義
var a int = iota
iota
也能夠用於表達式中,例如iota+50
表示將當前的iota值加上50。
每一個常量塊(const block)結構都會重置和初始化iota的值爲0。
func main() { const a = iota // a=0 const b = iota + 3 // b=3 const c,d = iota,iota+3 // c=0,d=3 const ( e = iota // e=0 f = iota + 4 // f=5 g // g=6 ) println(a,b,c,d,e,f,g) }
在使用變量以前,有兩個過程:聲明變量、變量賦值。聲明變量也常被稱爲"定義變量"。變量聲明後必須使用,不然會報錯。
定義變量的經常使用方式:
var identifier type
例如:
var a int var b bool var str string // 或者 var ( a int b bool str string )
當變量聲明的時候,會作默認的賦0初始化,每種數據類型的默認賦0初始化的0值不一樣。例如int類型的0值爲數值0,float的0值爲0.0,string類型的0值爲空"",bool類型的0值爲false,數據結構的0值爲nil,struct的0值爲字段所有賦0。
變量在編譯期間就能夠獲取到它的值,但若是賦值給變量的值須要通過運行期間的計算,則須要延遲到運行期間才能獲取對應的值。
var a int = 15 // 編譯期間賦值好 var b int = 15/3 // 編譯期間賦值好 var c = getNumber() // 運行期間才賦值
聲明和賦值能夠結合:
var a int = 15 var i = 5 var b bool = false var str string = "Hello World"
聲明和賦值結合的時候,對於簡單數據類型的值,能夠省略type部分,由於Go能夠根據值本身推斷出類型:
var a = 15 var b = false var str = "Hello World" var ( a = 15 b = false str = "Hello World" numShips = 50 city string )
由於要推斷數據類型,因此類型推斷操做是在運行期間完成的。
在使用推斷類型的賦值時,若是想要指定特定類型,須要顯式指定。例如整數數值推斷的類型爲int,要想讓它保存到int64中,則必須顯式指定類型:
var a int64 = 2
要推斷類型必須是聲明和賦值一塊兒的,不然沒有值,沒法根據值去推斷。例如var a
是錯的。
除了上面的推斷方式,經過:=
符號也能實現聲明和賦值結合,它也會根據數據類型進行推斷,連var關鍵字都省略了:
a := 50
可是:=
只能在函數代碼塊內部使用,在全局做用域下使用將報錯,由於類型推斷是在運行期執行的,而全局範圍內的變量聲明部分是在編譯期間就決定好的。例如,下面的將報錯:
a := 10 func main() { println(a) }
變量聲明以後不能再次聲明(除非在不一樣的做用域),以後只能使用=
進行賦值。例如,執行下面的代碼將報錯:
package main import ("fmt") func main(){ x:=10 fmt.Println("x =",x) x:=11 fmt.Println("x =",x) }
錯誤以下:
# command-line-arguments .\test.go:8:3: no new variables on left side of :=
報錯信息很明顯,:=
左邊沒有新變量。
若是仔細看上面的報錯信息,會發現no new variables
是一個複數。實際上,Go容許咱們使用:=
一次性聲明、賦值多個變量,並且只要左邊有任何一個新變量,語法就是正確的。
func main(){ name,age := "longshuai",23 fmt.Println("name:",name,"age:",age) // name從新賦值,由於有一個新變量weight weight,name := 90,"malongshuai" fmt.Println("name:",name,"weight:",weight) }
須要注意,name第二次被:=
賦值,Go第一次推斷出該變量的數據類型以後,就不容許:=
再改變它的數據類型,由於只有第一次:=
對name進行聲明,以後全部的:=
對name都只是簡單的賦值操做。
例如,下面將報錯:
weight,name := 90,80
錯誤信息:
.\test.go:11:14: cannot use 80 (type int) as type string in assignment
另外,變量聲明以後必須使用,不然會報錯,由於Go對規範的要求很是嚴格。例如,下面定義了weight
但卻沒使用:
weight,name := 90,"malongshuai" fmt.Println("name:",name)
錯誤信息:
.\test.go:11:2: weight declared and not used
Go語言的做用域採用的是詞法做用域,意味着文本段定義所在位置決定了可看見的值範圍。關於詞法做用域和動態做用域,詳細內容參見:一文搞懂:詞法做用域、動態做用域、回調函數、閉包
{...CODE...}
)的變量也是局部變量,除了代碼塊就消失不一樣scope的變量名能夠衝突,但建議採起名稱惟一的方式爲變量命名。