變量
-
聲明
var v1 int //變量 var v3 [10]int //數(shù)組 var v5 *int //指針 var ( //組合定義 v7 int v9 string ) -
初始化
定義有三種方式var v1 int = 1 var v1 = 1 //正確 v1 := 1 //正確,編譯器自動(dòng)推導(dǎo)出類(lèi)型雖然不用指定類(lèi)型,是因?yàn)榫幾g器承擔(dān)了這部分的工作。但是Go并不是動(dòng)態(tài)類(lèi)型語(yǔ)言,而是強(qiáng)類(lèi)型語(yǔ)言(靜態(tài)類(lèi)型語(yǔ)言)
賦值
初始化和賦值是兩個(gè)概念。Go語(yǔ)言支持多重賦值,如i,j = j,i實(shí)現(xiàn)變量值的交換。-
匿名變量
使用多個(gè)返回值和匿名變量結(jié)合代碼更加優(yōu)雅
如fun1函數(shù)有三個(gè)返回值func fun1() (ret1,ret2,ret3){ return 1,2,3 }如果只需要ret3,可以如下編寫(xiě)
_,_,ret := fun1()
常量
-
常量的定義
const Pi float64 = 3.14159265358 const mask = 1 << 3 //左移三位。常量的賦值是一個(gè)編譯期的行為,因此可以賦值為一個(gè)編譯期運(yùn)算的常量表達(dá)式 // 但是不能定義為運(yùn)行期才能得到的表達(dá)式 -
預(yù)定義的常量
Go語(yǔ)言預(yù)定義的常量包括: true ,false, itoaitoa 是一個(gè)自增常量,const關(guān)鍵字出現(xiàn)的時(shí)候被初始化為0,之后再遇到const,自增1
const ( c0 = itoa //0 c1 = itoa //1 a = 1 << itoa //2 ) -
枚舉類(lèi)型
GO語(yǔ)言不支持enum關(guān)鍵字。//注意,Go公有訪問(wèn)的屬性,變量,大寫(xiě)字母開(kāi)頭; 私有的以小寫(xiě)字母開(kāi)頭。 -
類(lèi)型
內(nèi)置的類(lèi)型有:- 布爾類(lèi)型,bool
- 整型: int8,byte,int16,int,unit,unitptr等
- 浮點(diǎn)類(lèi)型: float32 float64
- 復(fù)數(shù)類(lèi)型: complex64 complex128
- 字符串 string
- 字符 :有兩種,byte一種,另:unicode字符rune
- 錯(cuò)誤類(lèi)型 error
還有復(fù)合類(lèi)型:
? 指針(pointer) ? 數(shù)組(array) //需要注意再go語(yǔ)言中,數(shù)組是值類(lèi)型,即作為函數(shù)參數(shù)的時(shí)候,是復(fù)制傳值而不是傳址 ? 切片(slice) //數(shù)組是值類(lèi)型,定義之后無(wú)法修改,因此需要用切片 ? 字典(map) ? 通道(chan) ? 結(jié)構(gòu)體(struct) ? 接口(interface) -
數(shù)組切片
主要有兩種,一種基于現(xiàn)有數(shù)組的切片,一種直接創(chuàng)建切片- 基于數(shù)組的切片
package main import "fmt" func main() { var myArray [10]int = [10]int{1,2,3,4,5,6,7,8,9,10} //基于數(shù)組創(chuàng)建一個(gè)切片 var mySlice []int = myArray[:5] //前五個(gè)元素,使用格式myArray[first:last] <fmt class="Println">`</fmt>("Elementary of myArray:") for _,v := range myArray{ fmt.Print(v," ") } fmt.Println("\nElementary of mySlice:") for _,v := range mySlice{ fmt.Print(v," ") } fmt.p }運(yùn)行結(jié)果:
Elementary of myArray: 1 2 3 4 5 6 7 8 9 10 Elementary of mySlice: 1 2 3 4 5-
直接創(chuàng)建切片
mySlice1 := make([]int, 5) //創(chuàng)建個(gè)數(shù)為5的數(shù)組切片,并初始化為0mySlice2 := make([]int, 5, 10) //創(chuàng)建元素個(gè)數(shù)為5的數(shù)組切片,并初始化為0,還要預(yù)留10個(gè)元素的存儲(chǔ)空間myslice3 := []int{1,2,3,4,5} //創(chuàng)建并初始化
-
元素遍歷
for i, v := range myslice {}, range表達(dá)式有兩個(gè)返回值,第一個(gè)是索引,第二個(gè)是元素的值 -
動(dòng)態(tài)增減元素
與數(shù)組相比,數(shù)組切片多了一個(gè)存儲(chǔ)能力的概念,元素個(gè)數(shù)和分配的空間可以是兩個(gè)不同的值,合理設(shè)置存儲(chǔ)能力,可以大幅降低數(shù)組切片增加時(shí)內(nèi)存操作的頻率,從而提高程序性能。
如果定義的數(shù)組切片存儲(chǔ)能力過(guò)小,在超出的時(shí)候,內(nèi)存需要重新分配一塊較大的內(nèi)存,并把原先的內(nèi)存卡賦值過(guò)來(lái),開(kāi)銷(xiāo)較大
-
基于數(shù)組切片創(chuàng)建數(shù)組切片
oldSlice := []int(1,2,3,4,5) newSlice := oldSlice[:3] //取前三個(gè)。 -
內(nèi)容復(fù)制
copy(slice2, slice1) //slice1復(fù)制到slice2,長(zhǎng)度限制
-
map
在其他的語(yǔ)言中,map需要引入其他庫(kù),沒(méi)有作為內(nèi)置類(lèi)型。Golang中有var person map[int] string //聲明 // 變量名 鍵類(lèi)型 值類(lèi)型 person = make(map[int]string) //創(chuàng)建 person[1] = "John" //賦值 name, ok := person[2] //查詢 //值,查詢結(jié)果 delete(person, 1) //刪除
流程控制
流程控制一般有四種,條件語(yǔ)句,循環(huán)語(yǔ)句,選擇語(yǔ)句,跳轉(zhuǎn)語(yǔ)句。跳轉(zhuǎn)還比較少。
-
條件語(yǔ)句
if a < 5 { //條件不用括號(hào)包圍 return 0 } else { //花括號(hào)必須有且只能在這里 return 1 } -
選擇語(yǔ)句
switch i { //可以不指定變量,可以留空這里 case 0: fmt.Println(0) case 1: fmt.Println(1) default: fmt.Printf("default") } -
循環(huán)語(yǔ)句
GO語(yǔ)言中,只支持for語(yǔ)句的循環(huán),沒(méi)有when和whilesum := 0 for i:=0; i < 10; i++{ sum += i; } //或者 sum := 0 i := 0 for { sum += i++ if i > 10{ break } } 跳轉(zhuǎn)語(yǔ)句
goto語(yǔ)句被很多人看做不合時(shí)宜,如再c語(yǔ)言老師教學(xué)的時(shí)候會(huì)說(shuō)這個(gè)關(guān)鍵字被棄置了,不推薦使用。但是再go語(yǔ)言中竟然還支持,不知道為什么。
但是 **存在的既是合理的** ,第一次聽(tīng)說(shuō)是高三班主任的名言,印象深刻
```golang
func myfunc() {
i := 0
HERE:
fmt.Println(i)
i++
if i < 10 {
goto HERE
}
}
```
函數(shù)
- 函數(shù)定義
func FuncName (a int, b string) (ret int ,err error){
//func關(guān)鍵字 函數(shù)名 (參數(shù)列表) (返回值列表)
}
- 函數(shù)調(diào)用
import packname
...
packname.FuncName(1, "2")
//**必須注意,大寫(xiě)字母開(kāi)頭的為公有屬性,小寫(xiě)字母開(kāi)頭的私有屬性,這條規(guī)則同樣適用于變量和類(lèi)型**
- 不定參數(shù)
//定義
func func1(args ...int) //不定個(gè)數(shù)的參數(shù),但是類(lèi)型必須完全不是整型
//參數(shù)的傳遞
func1(1,2,3,4)
func1(args...)
func1(args[1:]...) //可以給傳遞一個(gè)數(shù)組切片,因?yàn)楸举|(zhì)上這個(gè)不定參數(shù)就是數(shù)組切片實(shí)現(xiàn)的,只是編寫(xiě)的時(shí)候不用太繁瑣
//任意類(lèi)型的不定參數(shù)
使用interface{}傳遞任意類(lèi)型的參數(shù)是go語(yǔ)言的默認(rèn)慣例
func myPrint(args ...interface{}){
for _,arg := range args{
switch arg.(type){
case int:
...
case string:
...
default:
...
}
}
}
- 多返回值
與其他語(yǔ)言不同的事,golang可以有多個(gè)返回值,比如查詢一個(gè)文件的大小,如果有就返回具體的值,如果為空返回nil,如果出錯(cuò)則返回具體的出錯(cuò)信息。如果要跳過(guò)某個(gè)具體的值,則使用_下劃線 - 匿名函數(shù)和閉包