布爾類型:bool; 整型:int8、byte、int16、int、uint、uintptr等; 浮點(diǎn)類型:float32、float64; 復(fù)數(shù)類型:complex64、complex128; 字符串:string; 字符類型:rune; 錯(cuò)誤類型:error; 此外,Go語(yǔ)言也支持以下這些復(fù)合類型: 指針(pointer) 數(shù)組(array) 切片(slice) 字典(map) 通道(chan) 結(jié)構(gòu)體(struct) 接口(interface)
var v1 bool v1 = true v2 := (1 == 2) // v2也會(huì)被推導(dǎo)為bool類型 布爾類型不能接受其他類型的賦值,不支持自動(dòng)或者強(qiáng)制的類型轉(zhuǎn)化。 以下會(huì)導(dǎo)致編譯出錯(cuò) var b bool b = 1
類 型 長(zhǎng)度 (字節(jié)) 值 范 圍 int8 1 128 ~ 127 uint8(即byte) 1 0 ~ 255 int16 2 -32768 ~ 32767 uint16 2 0 ~ 65535 int32 4 -2147483648 ~ 2 147483647 uint32 4 0 ~ 4294967295 int64 8 -9223372036854 775808 ~ 9223 372036854 uint64 8 0 ~ 18446744073 709551615 int 平臺(tái)相關(guān)(32位機(jī)器上同int32,64位機(jī)器同int64) 平臺(tái)相關(guān)(32位機(jī)器上同int32,64位機(jī)器同int64) uint 平臺(tái)相關(guān) 平臺(tái)相關(guān) uintptr 同指針在32位平臺(tái)下為4字節(jié),64位平臺(tái)下為8字節(jié)
常規(guī)開(kāi)發(fā)中使用int或者uint即可
需要注意的是: int和int32在Go語(yǔ)言里被認(rèn)為是兩種不同的類型,編譯器也不會(huì)幫你自動(dòng)做類型轉(zhuǎn)換,比如以下的例子會(huì)編譯錯(cuò)誤 var value2 int32 value1 := 64 //value1將會(huì)被自動(dòng)推導(dǎo)為int類型 value2 = value1 //編譯錯(cuò)誤,由于類型不一致 可以自己做強(qiáng)制轉(zhuǎn)換 value2 = (int32)value1
Go語(yǔ)言定義了兩個(gè)類型float32和float64,其中float32等價(jià)于C語(yǔ)言的float類型,float64等價(jià)于C語(yǔ)言的double類型 fvalue2:=12.0 其類型將被自動(dòng)設(shè)為float64,若是不加小數(shù)點(diǎn),則自動(dòng)推導(dǎo)為int類型 若是用==來(lái)判斷兩個(gè)浮點(diǎn)數(shù)是否相等,可能會(huì)導(dǎo)致不穩(wěn)定的結(jié)果
復(fù)數(shù)實(shí)際上由兩個(gè)實(shí)數(shù)構(gòu)成,一個(gè)表示實(shí)部real,一個(gè)表示虛部imag 復(fù)數(shù)的表示 var value1 complex64 value1 = 3.2+12i value2 := 3.2+12i //value2是complex128類型 value3 := complex(3.2,12) 對(duì)于一個(gè)復(fù)數(shù)z=complex(x,y),就可以通過(guò)Go語(yǔ)言的內(nèi)置函數(shù)real(z)獲取該復(fù)數(shù)的實(shí)部,也就是x,通過(guò)imag(z)獲取該復(fù)數(shù)的虛部,也就是y
Go語(yǔ)言中字符串的聲明和初始化舉例如下
func main(){ var str string str="hello world" ch:=str[0] fmt.//執(zhí)行結(jié)果 The length of “hello world” is 11 The first character of “hello world” is h. 字符串的內(nèi)容可以用類似于數(shù)組下標(biāo)的方式獲取,但是與數(shù)組不同,字符串的內(nèi)容不能在初始化之后被修改 如上述 str[0]=’x’ 會(huì)出現(xiàn)編譯錯(cuò)誤 len(str) Go語(yǔ)言內(nèi)置函數(shù),用于獲取字符串長(zhǎng)度在Go語(yǔ)言中支持兩個(gè)字符類型,一個(gè)是byte(實(shí)際上是unit8的別名)代表UTF-8字符串的單個(gè)字節(jié)的值;另一個(gè)是rune,代表單個(gè)unicode字符。
一些常規(guī)的數(shù)組聲明方法:
func main(){ var arr [32]byte //定義了一個(gè)長(zhǎng)度為32的byte類型數(shù)組 arr[0]=1 fmt.Print(arr) fmt.Print(len(arr)) var arr2 [2]struct { x, y int32 } //復(fù)雜類型數(shù)組 fmt.Print(arr2) var arr3 [1000]*float64 //指針類型數(shù)組 [3][5]int // 二維數(shù)組 --表示三行五列的二維數(shù)組 //可以用Go語(yǔ)言的內(nèi)置函數(shù)len()來(lái)獲取。下面是一個(gè)獲取數(shù)組arr元素個(gè)數(shù)的寫(xiě)法: arrLength := len(arr)}元素訪問(wèn)
for i:=0;i<len(arr);i++{ fmt.Print(arr[i]) }j:表示角標(biāo),v表示值。若是只需要用到其中一個(gè),另一個(gè)可用匿名函數(shù)代替
for j,v :=range arr{ fmt.Println("arr element[", j, "]=", v) }值類型 需要特別注意的是,在Go語(yǔ)言中數(shù)組是一個(gè)值類型,所有的值類型變量在賦值和作為參數(shù)傳遞時(shí)都將產(chǎn)生一次復(fù)制動(dòng)作。如果將數(shù)組作為函數(shù)的參數(shù)類型,則在函數(shù)調(diào)用時(shí)該參數(shù)將發(fā)生數(shù)據(jù)復(fù)制。因此,在函數(shù)體中無(wú)法修改傳入的數(shù)組內(nèi)容,因?yàn)楹瘮?shù)內(nèi)操作的只是傳入數(shù)組的一個(gè)副本; 如下示例:
func main(){ array := [5]int{1,2,3,4,5} // 定義并初始化一個(gè)數(shù)組 modify(array) // 傳遞給一個(gè)函數(shù),并試圖在函數(shù)體內(nèi)修改這個(gè)數(shù)組內(nèi)容 fmt.Println("In main(), array values:", array)}func modify(array [5]int) { array[0] = 10 // 試圖修改數(shù)組的第一個(gè)元素 fmt.Println("In modify(), array values:", array)}執(zhí)行結(jié)果: In modify(), array values: [10 2 3 4 5] In main(), array values: [1 2 3 4 5]
上述所知數(shù)組的特點(diǎn):數(shù)組的長(zhǎng)度在定義之后無(wú)法再次修改;數(shù)組是指類型,每次傳遞都將產(chǎn)生一份副本。顯然這種數(shù)據(jù)結(jié)構(gòu)是無(wú)法滿足開(kāi)發(fā)者的真正需求。 不用失望,Go語(yǔ)言提供了數(shù)組切片(slice)這個(gè)非??岬墓δ軄?lái)彌補(bǔ)數(shù)組的不足。 初看起來(lái),數(shù)組切片就像是一個(gè)指向數(shù)組的指針,實(shí)際上它擁有自己的數(shù)據(jù)結(jié)構(gòu),而不僅僅是一個(gè)指針。數(shù)組切片的數(shù)據(jù)結(jié)構(gòu)可以抽象為以下3個(gè)變量: 1、一個(gè)指向原生數(shù)組的指針; 2、數(shù)組切片中的元素個(gè)數(shù); 3、數(shù)組切片已分配的存儲(chǔ)空間;
創(chuàng)建數(shù)組切片: 創(chuàng)建數(shù)組切片的方法主要有兩種-基于數(shù)組和直接創(chuàng)建; 基于數(shù)組方法示例:
func main(){ // 先定義一個(gè)數(shù)組 var myArray [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} // 基于數(shù)組創(chuàng)建一個(gè)數(shù)組切片 var mySlice []int = myArray[:5]//前五個(gè)元素創(chuàng)建切片數(shù)組 var mySlice2 []int = myArray[5:]//后五個(gè)元素創(chuàng)建切片數(shù)組 fmt.Println("Elements of myArray: ") for _, v := range myArray { fmt.Print(v, " ") } fmt.Println("/nElements of mySlice: ") for _, v := range mySlice { fmt.Print(v, " ") } fmt.Println("/nElements of mySlice2: ") for _, v := range mySlice2 { fmt.Print(v, " ") } fmt.Println()}Go語(yǔ)言支持用myArray[first:last]這樣的方式來(lái)基于數(shù)組生成一個(gè)數(shù)組切片,下標(biāo)包含first不包含last,類似subString方法 直接創(chuàng)建示例: Go語(yǔ)言提供的內(nèi)置函數(shù)make()可以用于靈活地創(chuàng)建數(shù)組切片。
func main(){ //創(chuàng)建一個(gè)初始元素個(gè)數(shù)為5的數(shù)組切片,元素初始值為0: mySlice1 := make([]int, 5) //創(chuàng)建一個(gè)初始元素個(gè)數(shù)為5的數(shù)組切片,元素初始值為0,并預(yù)留10個(gè)元素的存儲(chǔ)空間: mySlice2 := make([]int, 5, 10) //直接創(chuàng)建并初始化包含5個(gè)元素的數(shù)組切片: mySlice3 := []int{1, 2, 3, 4, 5} for _,v:=range mySlice1{ fmt.Print(v) } for _,v:=range mySlice2{ fmt.Print(v) } for _,v:=range mySlice3{ fmt.Print(v) }}元素遍歷同普通數(shù)組 動(dòng)態(tài)增減元素: 數(shù)組切片支持Go語(yǔ)言內(nèi)置的cap()函數(shù)和len()函數(shù),其中cap()函數(shù)返回的是數(shù)組切片分配的空間大小,而len()函數(shù)返回的是數(shù)組切片中當(dāng)前所存儲(chǔ)的元素個(gè)數(shù)。 如果需要往上例中mySlice已包含的5個(gè)元素后面繼續(xù)新增元素,可以使用append()函數(shù)。 如:mySlice = append(mySlice,1,2,3) 函數(shù)append()的第二個(gè)參數(shù)是一個(gè)不定參數(shù),我們可以按照我們的需求添加,甚至直接將一個(gè)數(shù)組切片追加到另一個(gè)數(shù)組切片的末尾。 如:mySlice = append(mySlice,mySlice2…) 我們?cè)诘诙€(gè)參數(shù)mySlice2后面加了三個(gè)點(diǎn),如果省略的話,會(huì)有編譯錯(cuò)誤。因?yàn)閙ySlice中的元素類型是int,所以直接傳遞mySlice2是行不通的。加上省略號(hào)相當(dāng)于把mySlice2包含的所有元素打散后傳入。 基于數(shù)組切片后創(chuàng)建數(shù)組切片 oldSlice := []int{1, 2, 3, 4, 5} newSlice := oldSlice[:3] // 基于oldSlice的前3個(gè)元素構(gòu)建新數(shù)組切片 有意思的是,選擇的oldSlicef元素范圍甚至可以超過(guò)所包含的元素個(gè)數(shù),比如newSlice可以基于oldSlice的前6個(gè)元素創(chuàng)建,雖然oldSlice只包含5個(gè)元素。只要這個(gè)選擇的范圍不超過(guò)oldSlice存儲(chǔ)能力(即cap()返回的值),那么這個(gè)創(chuàng)建程序就是合法的。newSlice中超出 oldSlice元素的部分都會(huì)填上0。 內(nèi)容復(fù)制 數(shù)組切片支持Go語(yǔ)言的另一個(gè)內(nèi)置函數(shù)copy(),用于將內(nèi)容從一個(gè)數(shù)組切片復(fù)制到另一個(gè)數(shù)組切片。如果將入的兩個(gè)數(shù)組切片不一樣大,會(huì)按照較小的那個(gè)數(shù)組切片的元素個(gè)數(shù)進(jìn)行復(fù)制。 slice1 := []int{1, 2, 3, 4, 5} slice2 := []int{5, 4, 3} copy(slice2, slice1) // 只會(huì)復(fù)制slice1的前3個(gè)元素到slice2中 copy(slice1, slice2) // 只會(huì)復(fù)制slice2的3個(gè)元素到slice1的前3個(gè)位置
變量聲明: 如:var myMap map[string] PersonInfo 聲明一個(gè)map,key是string類型,value是PersonInfo類型
創(chuàng)建: 我們可以使用Go語(yǔ)言的內(nèi)置函數(shù)make()來(lái)創(chuàng)建一個(gè)新map。下面的這個(gè)例子創(chuàng)建了一個(gè)key類型為string、值類型為PersonInfo的map: myMap = make(map[string] PersonInfo) 也可以創(chuàng)建一個(gè)初始存儲(chǔ)能力為100的map: 如:myMap = make(map[string] PersonInfo,100) 創(chuàng)建并初始化: myMap = map[string] PersonInfo{ “1234”: PersonInfo{“1”, “Jack”, “Room 101,…”}, }
元素賦值: myMap[“test”] = PersonInfo{“1”, “Jack”, “Room 101,…”}
元素刪除: delete(myMap, “test”)
元素查找: value, ok := myMap[“test”] if ok { // 找到了 // 處理找到的value } 判斷是否成功找到特定的鍵,不需要檢查渠道的值是否為nil,只需要查看第二個(gè)返回值ok。 示例:
package mainimport ("fmt")type PersonInfo struct { ID string Name string Address string}func main(){ var personDB map[string] PersonInfo personDB = make(map[string] PersonInfo) // 往這個(gè)map里插入幾條數(shù)據(jù) personDB["test"] = PersonInfo{"12345", "Tom", "Room 203,..."} personDB["test1"] = PersonInfo{"1", "Jack", "Room 101,..."} // 從這個(gè)map查找鍵為"1234"的信息 person, ok := personDB["test"] // ok是一個(gè)返回的bool型,返回true表示找到了對(duì)應(yīng)的數(shù)據(jù) if ok { fmt.Println("Found person", person.Name, "with ID test.") } else { fmt.Println("Did not find person with ID test.") }}新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注