編譯運(yùn)行
代碼的編譯運(yùn)行
go build : 產(chǎn)生一個可執(zhí)行二進(jìn)制文件
go run :
go install : 會在pkg里面產(chǎn)生一個.a 的庫
go clean : 移除當(dāng)前源碼包和關(guān)聯(lián)碼包里面編譯生成的文件
go fmt : 格式化代碼格式。eg: gofmt -w -l src
go get :動態(tài)獲取遠(yuǎn)程代碼包
go test : 會讀取源代碼目錄下面名為*_test.go文件,生成并運(yùn)行測試用的可執(zhí)行文件。
go tool :
go generate :
包結(jié)構(gòu)
程序都是用package來組織;在每個go文件前面,需要先聲明一下是屬于哪個package;
其中package main 和 func main 是程序執(zhí)行的入口。
package的名字最好能跟src目錄下的結(jié)構(gòu)一致
每個package的文件都有一個保留的init函數(shù)。不會返回任何值,也不能傳入任何參數(shù)。go會自動調(diào)用init。
import
import 引入的路徑推薦用絕對路徑
點(diǎn)操作
我們有時候會看到如下的方式導(dǎo)入包
import(
. "fmt"
)
這個點(diǎn)操作的含義就是這個包導(dǎo)入之后在你調(diào)用這個包的函數(shù)時,你可以省略前綴的包名,也就是前面你調(diào)用的fmt.Println("hello world")可以省略的寫成Println("hello world")別名操作
別名操作顧名思義我們可以把包命名成另一個我們用起來容易記憶的名字。別名操作的話調(diào)用包函數(shù)時前綴變成了我們的前綴,即f.Println("hello world")
import(
f "fmt"
)
- _ 操作
這個操作經(jīng)常是讓很多人費(fèi)解的一個操作符。 _ 操作其實(shí)是引入該包,而不直接使用包里面的函數(shù),而是調(diào)用了該包里面的init函數(shù)。請看下面這個import
import (
"database/sql"
_ "github.com/ziutek/mymysql/godrv"
)
變量
命名:
- 名字是區(qū)分大小寫
- 關(guān)鍵字不能用來命名。
聲明:
用 var (變量), const(常量) , type (定義一個新的命名類型,但是不同的命名類型都是完全不相同,就算他們underlying-type 是相同的), func (函數(shù))。
聲明的位置如果在func里面,則是本地變量。 如果在package 又不在func里,是package level。 package level 的表示在pacakge里面的,都是可見
var name type = expression
提供一個語法糖: name := expression
指針:
指向變量的地址,如果有C語言開發(fā)經(jīng)驗(yàn),這個很好理解。
可以使用new(T) 的方式,創(chuàng)建一個值為0,返回類型為 T* 的地址。
_(下劃線) 是個特殊的變量名,任何賦予它的值都會被丟棄
iota枚舉:聲明enum的時候采用,默認(rèn)開始是0, 每增一行+1
大寫字母開始的變量是可導(dǎo)出;小寫字母開頭是不可導(dǎo)出的
數(shù)組
array
是數(shù)組類型。 格式:
var arr [n] type { }
n表示長度, type 是類型, 通過[ ] 來讀取或者賦值。 { } 里面就是初始值,可以不寫
slice
slice總是指向一個底層array,slice的聲明也可以像array一樣,只是 不需要長度。
對于slice有幾個有用的內(nèi)置函數(shù):
有用的幾個內(nèi)置函數(shù):
- len 獲取slice的長度
- cap 獲取slice的最大容量
- append 向slice里面追加一個或者多個元素,然后返回一個和slice一樣類型的slice
- copy 函數(shù)copy從源slice的src中復(fù)制元素到目標(biāo)dst,并且返回復(fù)制的元素的個數(shù)
map
格式為
map[keyType] valueType
聲明格式
// 聲明一個key是字符串,值為int的字典,這種方式的聲明需要在使用之前使用make初始化
var numbers map[string] int
// 另一種map的聲明方式
numbers = make(map[string] int)
基本操作
- map的初始化可以通過key:val的方式初始化值,同時map內(nèi)置有判斷是否存在key的方式
// map有兩個返回值,第二個返回值,如果不存在key,那么ok為false,如果存在ok為true
csharpRating, ok := rating["C#"] - 通過delete刪除map的元素:delete(rating, "C") // 刪除key為C的元素
注意
map和其他基本型別不同,它不是thread-safe,在多個go-routine存取時,必須使用mutex lock機(jī)制
make、new操作
make用于內(nèi)建類型(map、slice 和channel)的內(nèi)存分配。new 用于各種類型的內(nèi)存分配。
內(nèi)建函數(shù)new本質(zhì)上說跟其它語言中的同名函數(shù)功能一樣:new(T)分配了零值填充的 T 類型的內(nèi)存空間,并且返回其地址,即一個*T類型的值。用Go的術(shù)語說,它返回了一個指針,指向新分配的類型 T 的零值。有一點(diǎn)非常重要:
new 返回指針。
內(nèi)建函數(shù)make(T, args)與new(T)有著不同的功能,make只能創(chuàng)建slice、map和channel,并且返回一個有初始值(非零)的 T 類型,而不是*T。本質(zhì)來講,導(dǎo)致這三個類型有所不同的原因是指向數(shù)據(jù)結(jié)構(gòu)的引用在使用前必須被初始化。例如,一個slice,是一個包含指向數(shù)據(jù)(內(nèi)部array)的指針、長度和容量的三項(xiàng)描述符;在這些項(xiàng)目被初始化之前,slice為nil。對于slice、map和channel來說,make初始化了內(nèi)部的數(shù)據(jù)結(jié)構(gòu),填充適當(dāng)?shù)闹怠?/p>