跨平臺(tái)編譯
SET CGO_ENABLED=0 // 禁用CGO
SET GOOS=linux // 目標(biāo)平臺(tái)是linux
SET GOARCH=amd64 // 目標(biāo)處理器架構(gòu)是amd64
godep 依賴(lài)管理工具
執(zhí)行以下命令安裝godep工具
go get github.com/tools/godep
godep save 將依賴(lài)項(xiàng)輸出并復(fù)制到Godeps.json文件中
godep go 使用保存的依賴(lài)項(xiàng)運(yùn)行g(shù)o工具
godep get 下載并安裝具有指定依賴(lài)項(xiàng)的包
godep path 打印依賴(lài)的GOPATH路徑
godep restore 在GOPATH中拉取依賴(lài)的版本
godep update 更新選定的包或go版本
godep diff 顯示當(dāng)前和以前保存的依賴(lài)項(xiàng)集之間的差異
godep version 查看版本信息
go module
go module是Go1.11版本之后官方推出的版本管理工具谆焊,并且從Go1.13版本開(kāi)始摩桶,go module將是Go語(yǔ)言默認(rèn)的依賴(lài)管理工具舵稠。
基礎(chǔ)語(yǔ)法
fmt.Println() 打印
格式符:%o輸出八進(jìn)制,%d輸出十進(jìn)制锣险,%x輸出十六進(jìn)制滩租,%f輸出浮點(diǎn)型數(shù)據(jù),%c輸出單個(gè)字符,%s輸出字符串句伶,%l輸出長(zhǎng)整型。但是也有稍微不是很常用的格式符陆淀,%p就是其中之一考余。相信大家在日常中使用得比較少,其實(shí)它的輸出格式也是六進(jìn)制轧苫,跟%x的區(qū)別在于楚堤,%p輸出的長(zhǎng)度是一致的8位16進(jìn)制符(即32位2進(jìn)制符)。
cap可以求出slice最大擴(kuò)張容量含懊,不能超出數(shù)組限制
len 長(zhǎng)度
數(shù)組
var 變量名= [長(zhǎng)度]類(lèi)型=(值)
var 變量名= [...]類(lèi)型=(值) //未知長(zhǎng)度
var 變量名= [5]類(lèi)型=(索引:值,索引:值) //給指定索引賦值
var 變量名= [...]struct=({名稱(chēng):類(lèi)型}{值:值}) //前面聲明名稱(chēng)類(lèi)型后面指定值
例:var test= [...]struct {
name string
age uint8
}{
{"user1", 10}, // 可省略元素類(lèi)型身冬。
{"user2", 20}, // 別忘了最后一行的逗號(hào)。
}
內(nèi)置函數(shù) len 和 cap 都返回?cái)?shù)組長(zhǎng)度 (元素?cái)?shù)量)岔乔。
數(shù)組傳參
(定義函數(shù)內(nèi)變量名 *[長(zhǎng)度]類(lèi)型)
切片 Slice
切片的定義:var 變量名 []類(lèi)型酥筝,
nil 判斷切片是否為空
通過(guò)make來(lái)創(chuàng)建切片
var slice []type = make([]type, len)
slice := make([]type, len)
slice := make([]type, len, cap)
append
尾部添加
copy :函數(shù) copy 在兩個(gè) slice 間復(fù)制數(shù)據(jù),復(fù)制長(zhǎng)度以 len 小的為準(zhǔn)雏门。兩個(gè) slice 可指向同一底層數(shù)組嘿歌,允許元素區(qū)間重疊。
指針
&(取地址)和*(根據(jù)地址取值)
取變量指針的語(yǔ)法如下:
ptr := &v // v的類(lèi)型為T(mén)
v:代表被取地址的變量茁影,類(lèi)型為T(mén)
ptr:用于接收地址的變量宙帝,ptr的類(lèi)型就為T,稱(chēng)做T的指針類(lèi)型募闲。代表指針茄唐。
new
聲明
func new(Type) *Type
1.Type表示類(lèi)型,new函數(shù)只接受一個(gè)參數(shù)蝇更,這個(gè)參數(shù)是一個(gè)類(lèi)型
2.*Type表示類(lèi)型指針沪编,new函數(shù)返回一個(gè)指向該類(lèi)型內(nèi)存地址的指針。
make
make也是用于內(nèi)存分配的年扩,區(qū)別于new蚁廓,它只用于slice、map以及chan的內(nèi)存創(chuàng)建厨幻,而且它返回的類(lèi)型就是這三個(gè)類(lèi)型本身相嵌,而不是他們的指針類(lèi)型
聲明
func make(t Type, size ...IntegerType) Type
new與make的區(qū)別
1.二者都是用來(lái)做內(nèi)存分配的腿时。
2.make只用于slice、map以及channel的初始化饭宾,返回的還是這三個(gè)引用類(lèi)型本身批糟;
3.而new用于類(lèi)型的內(nèi)存分配,并且內(nèi)存對(duì)應(yīng)的值為類(lèi)型零值看铆,返回的是指向類(lèi)型的指針徽鼎。
map
map是一種無(wú)序的基于key-value的數(shù)據(jù)結(jié)構(gòu),Go語(yǔ)言中的map是引用類(lèi)型弹惦,必須初始化才能使用
聲明
map[KeyType]ValueType
KeyType:表示鍵的類(lèi)型否淤。
ValueType:表示鍵對(duì)應(yīng)的值的類(lèi)型。
map類(lèi)型的變量默認(rèn)初始值為nil棠隐,需要使用make()函數(shù)來(lái)分配內(nèi)存石抡。語(yǔ)法為:
make(map[KeyType]ValueType, [cap])
也可以在聲明時(shí)填充元素
userInfo := map[string]string{
"username": "pprof.cn",
"password": "123456",
}
判斷值是否存在
Go語(yǔ)言中有個(gè)判斷map中鍵是否存在的特殊寫(xiě)法,格式如下:
value, ok := map[key]
//例子
func main() {
scoreMap := make(map[string]int)
scoreMap["張三"] = 90
scoreMap["小明"] = 100
// 如果key存在ok為true,v為對(duì)應(yīng)的值助泽;不存在ok為false,v為值類(lèi)型的零值
v, ok := scoreMap["張三"]
if ok {
fmt.Println(v)
} else {
fmt.Println("查無(wú)此人")
}
}
map遍歷
scoreMap := make(map[string]int)
scoreMap["張三"] = 90
scoreMap["小明"] = 100
scoreMap["王五"] = 60
for k, v := range scoreMap {
fmt.Println(k, v)
}
//或者只遍歷key
for k := range scoreMap {
fmt.Println(k)
}
map刪除
delete(map, key)
map:表示要?jiǎng)h除鍵值對(duì)的map
key:表示要?jiǎng)h除的鍵值對(duì)的鍵
結(jié)構(gòu)體
自定義類(lèi)型
//將MyInt定義為int類(lèi)型
type MyInt int
//通過(guò)Type關(guān)鍵字的定義啰扛,MyInt就是一種新的類(lèi)型,它具有int的特性嗡贺。
類(lèi)型別名
//類(lèi)型別名規(guī)定:TypeAlias只是Type的別名隐解,本質(zhì)上TypeAlias與Type是同一個(gè)類(lèi)型。
type TypeAlias = Type
結(jié)構(gòu)體
使用type和struct關(guān)鍵字來(lái)定義結(jié)構(gòu)體
type 類(lèi)型名 struct {
字段名 字段類(lèi)型
字段名 字段類(lèi)型
…
}
1.類(lèi)型名:標(biāo)識(shí)自定義結(jié)構(gòu)體的名稱(chēng)暑刃,在同一個(gè)包內(nèi)不能重復(fù)。
2.字段名:表示結(jié)構(gòu)體字段名膜眠。結(jié)構(gòu)體中的字段名必須唯一岩臣。
3.字段類(lèi)型:表示結(jié)構(gòu)體字段的具體類(lèi)型。
舉個(gè)例子宵膨,我們定義一個(gè)Person(人)結(jié)構(gòu)體架谎,代碼如下:
type person struct {
name string
city string
age int8
}
//或者同類(lèi)型寫(xiě)在一行
type person1 struct {
name, city string
age int8
}
結(jié)構(gòu)體實(shí)例化
只有當(dāng)結(jié)構(gòu)體實(shí)例化時(shí),才會(huì)真正地分配內(nèi)存辟躏。也就是必須實(shí)例化后才能使用結(jié)構(gòu)體的字段谷扣。
結(jié)構(gòu)體本身也是一種類(lèi)型,我們可以像聲明內(nèi)置類(lèi)型一樣使用var關(guān)鍵字聲明結(jié)構(gòu)體類(lèi)型捎琐。
var 結(jié)構(gòu)體實(shí)例 結(jié)構(gòu)體類(lèi)型
例子
type person struct {
name string
city string
age int8
}
func main() {
var p1 person
p1.name = "pprof.cn"
p1.city = "北京"
p1.age = 18
fmt.Printf("p1=%v\n", p1) //p1={pprof.cn 北京 18}
fmt.Printf("p1=%#v\n", p1) //p1=main.person{name:"pprof.cn", city:"北京", age:18}
}
匿名結(jié)構(gòu)體
var user struct{Name string; Age int}
指針結(jié)構(gòu)體
var p2 = new(person)
使用&對(duì)結(jié)構(gòu)體進(jìn)行取地址操作相當(dāng)于對(duì)該結(jié)構(gòu)體類(lèi)型進(jìn)行了一次new實(shí)例化操作会涎。
p3 := &person{}
結(jié)構(gòu)體初始化
鍵值對(duì)
p6 := &person{
name: "pprof.cn",
city: "北京",
age: 18,
}
可以不寫(xiě)鍵值
p8 := &person{
"pprof.cn",
"北京",
18,
}
注意: 1.必須初始化結(jié)構(gòu)體的所有字段。
2.初始值的填充順序必須與字段在結(jié)構(gòu)體中的聲明順序一致瑞凑。
3.該方式不能和鍵值初始化方式混用
創(chuàng)建構(gòu)造函數(shù)
func newPerson(name, city string, age int8) *person {
return &person{
name: name,
city: city,
age: age,
}
}
方法和接收者
聲明
func (接收者變量 接收者類(lèi)型) 方法名(參數(shù)列表) (返回參數(shù)) {
函數(shù)體
}
指針類(lèi)型接收者
1.需要修改接收者中的值
2.接收者是拷貝代價(jià)比較大的大對(duì)象
3.保證一致性末秃,如果有某個(gè)方法使用了指針接收者,那么其他的方法也應(yīng)該使用指針接收者籽御。
func (p *Person) SetAge(newAge int8) {
p.age = newAge
}
值類(lèi)型接收者
修改操作只是針對(duì)副本练慕,無(wú)法修改接收者變量本身惰匙。
func (p Person) SetAge2(newAge int8) {
p.age = newAge
}
嵌套結(jié)構(gòu)體
//Address 地址結(jié)構(gòu)體
type Address struct {
Province string
City string
}
//User 用戶(hù)結(jié)構(gòu)體
type User struct {
Name string
Gender string
Address Address
}
原文 馬魯南的個(gè)人博客