變量聲明方法有:1、使用var來聲明一個(gè)變量,并指明變量的數(shù)據(jù)類型,語(yǔ)法“var 變量名 類型 = 表達(dá)式”;2、利用“:=”符進(jìn)行短變量聲明,語(yǔ)法“變量名 := 表達(dá)式”。使用短變量聲明時(shí),可以省去var關(guān)鍵字以及類型信息,變量的默認(rèn)類型是bool、rune、int、float64、complex128或string。
本教程操作環(huán)境:windows7系統(tǒng)、GO 1.18版本、Dell G3電腦。
學(xué)習(xí)靜態(tài)語(yǔ)言有別于動(dòng)態(tài)語(yǔ)言的一個(gè)重要特征:變量聲明。
編程語(yǔ)言的編譯器或解釋器是如何知道一個(gè)變量所能引用的內(nèi)存區(qū)域邊界呢?
動(dòng)態(tài)語(yǔ)言和靜態(tài)語(yǔ)言有不同的處理方式:
-
動(dòng)態(tài)語(yǔ)言(比如 Python、Ruby 等)的解釋器可以在運(yùn)行時(shí)通過對(duì)變量賦值的分析,自動(dòng)確定變量的邊界。并且在動(dòng)態(tài)語(yǔ)言中,一個(gè)變量可以在運(yùn)行時(shí)被賦予大小不同的邊界。
-
而靜態(tài)編程語(yǔ)言在這方面的“體驗(yàn)略差”。靜態(tài)類型語(yǔ)言編譯器必須明確知道一個(gè)變量的邊界才允許使用這個(gè)變量,但靜態(tài)語(yǔ)言編譯器又沒能力自動(dòng)提供這個(gè)信息,這個(gè)邊界信息必須由這門語(yǔ)言的使用者提供,于是就有了“變量聲明”。通過變量聲明,語(yǔ)言使用者可以顯式告知編譯器一個(gè)變量的邊界信息。在具體實(shí)現(xiàn)層面呢,這個(gè)邊界信息由變量的類型屬性賦予。
作為身處?kù)o態(tài)編程語(yǔ)言陣營(yíng)的 Go 語(yǔ)言,它沿襲了靜態(tài)語(yǔ)言的這一要求:使用變量之前需要先進(jìn)行變量聲明。
[golang] 變量聲明和初始化 var, :=, new() 和 make()
go語(yǔ)言中,提供了多種變量聲明和初始化的方法。這里著重一一說明。并提供一個(gè)簡(jiǎn)單的指南。
指南
- 使用
make()
,來初始化slice
,map
和channel
。 - 大多數(shù)場(chǎng)合,類型明確的場(chǎng)合下,使用短變量聲明方式
:=
。 - 當(dāng)使用文字方式初始化一個(gè)變量,并且需要指明類型時(shí),使用
var
變量聲明方式。 - 避免使用
new()
,除非你需要一個(gè)指針變量。
變量聲明方式
go語(yǔ)言可以使用 var
來聲明一個(gè)變量,并指明變量的數(shù)據(jù)類型。
// 初始化整數(shù)變量,值為10。 var v int = 10 fmt.Println(v) // 輸出: 10 // 變量聲明: 一個(gè)slice變量 var vSlice []int = []int{1, 2, 3, 4} fmt.Println(vSlice, "type: ", reflect.TypeOf(vSlice).Kind()) // 輸出: [1 2 3 4] type: slice // 短變量聲明: 一個(gè)map變量,指向的值為[] var vMap map[string]int = map[string]int{ "a": 1, "b": 2, } fmt.Println(vMap) // 輸出: map[a:1 b:2]
短變量聲明方式
short variable declarations 符號(hào): :=
。
短變量聲明時(shí),變量的默認(rèn)類型是: bool
, rune
, int
, float64
, complex128
or string
// 短變量聲明: 一個(gè)整數(shù)變量。 sdvInt := 10 fmt.Println(sdvInt, "type: ", reflect.TypeOf(sdvInt).Kind()) // 輸出: 10 type: int // 短變量聲明: 一個(gè)slice變量 sdvSlice := []int{1, 2, 3, 4} fmt.Println(sdvSlice, "type: ", reflect.TypeOf(sdvSlice).Kind()) // 輸出: [1 2 3 4] type: slice // 短變量聲明: 一個(gè)map變量,指向的值為[] sdvMap := map[string]int{ "a": 1, "b": 2, } fmt.Println(sdvMap) // 輸出: map[a:1 b:2]
new(T)
new(T)
的特點(diǎn):
- 根據(jù)類型T分配內(nèi)存
- 設(shè)置內(nèi)存為0
- 返回內(nèi)存的指針
// 初始化一個(gè)整數(shù)指針變量,指向的值為0 var i3 *int = new(int) fmt.Println(*i3) // 初始化一個(gè)slice指針變量 var i4 = new([10]int)[0:5] fmt.Println(i4, "type: ", reflect.TypeOf(i4).Kind()) // 輸出: [0 0 0 0 0] type: slice // 初始化一個(gè)map指針變量,指向的值為[] var i5 *map[string]int = new(map[string]int) fmt.Println(*i5) // 輸出: map[] // 初始化一個(gè)chan指針變量,指向的值為nil var i6 *chan int = new(chan int) fmt.Println(*i6) // 輸出: nil
make()
make只用于初始化 slice
,map
和 channel
。
// make只能用于創(chuàng)建slice, map, channel // 切片類型(slice) makeSlice := make([]int, 5, 10) fmt.Println(makeSlice) // 輸出: [0 0 0 0 0] // Map 類型 var makeMap map[string]int = make(map[string]int) fmt.Println(makeMap) // 輸出: map[] // Channel 類型 var makeChan chan int32 = make(chan int32, 100) fmt.Println(makeChan) // 輸出: 0xc000112000
完整源碼
package main import ( "fmt" "reflect" ) func main() { // 初始化整數(shù)變量,值為10。 var v int = 10 fmt.Println(v) // 輸出: 10 // 變量聲明: 一個(gè)slice變量 var vSlice []int = []int{1, 2, 3, 4} fmt.Println(vSlice, "type: ", reflect.TypeOf(vSlice).Kind()) // 輸出: [1 2 3 4] type: slice // 短變量聲明: 一個(gè)map變量,指向的值為[] var vMap map[string]int = map[string]int{ "a": 1, "b": 2, } fmt.Println(vMap) // 輸出: map[a:1 b:2] // 短變量聲明: 一個(gè)整數(shù)變量。 sdvInt := 10 fmt.Println(sdvInt, "type: ", reflect.TypeOf(sdvInt).Kind()) // 輸出: 10 type: int // 短變量聲明: 一個(gè)slice變量 sdvSlice := []int{1, 2, 3, 4} fmt.Println(sdvSlice, "type: ", reflect.TypeOf(sdvSlice).Kind()) // 輸出: [1 2 3 4] type: slice // 短變量聲明: 一個(gè)map變量,指向的值為[] sdvMap := map[string]int{ "a": 1, "b": 2, } fmt.Println(sdvMap) // 輸出: map[a:1 b:2] // 初始化一個(gè)整數(shù)指針變量,指向的值為0 var newInt *int = new(int) fmt.Println(*newInt) // 初始化一個(gè)slice指針變量 var newSlice = new([10]int)[0:5] fmt.Println(newSlice, "type: ", reflect.TypeOf(newSlice).Kind()) // 輸出: [0 0 0 0 0] type: slice // 初始化一個(gè)map指針變量,指向的值為[] var newMap *map[string]int = new(map[string]int) fmt.Println(*newMap) // 輸出: map[] // 初始化一個(gè)chan指針變量,指向的值為nil var newChan *chan int = new(chan int) fmt.Println(*newChan) // 輸出: nil // make只能用于創(chuàng)建slice, map, channel // 切片類型(slice) makeSlice := make([]int, 5, 10) fmt.Println(makeSlice) // 輸出: [0 0 0 0 0] // Map 類型 var makeMap map[string]int = make(map[string]int) fmt.Println(makeMap) // 輸出: map[] // Channel 類型 var makeChan chan int32 = make(chan int32, 100) fmt.Println(makeChan) // 輸出: 0xc000112000 }
【