Go初识与问题
變量&常量
變量
-
命名
由字母、數(shù)字、下劃線組成,首個(gè)字符不能是數(shù)字關(guān)鍵字、保留字不能作為變量名變量名字區(qū)分大小寫駝峰命名 -
聲明
1. var : 全局變量var 變量名稱 類型var 變量名稱1,變量名稱2 類型 (同一種類型)var (變量名稱1 類型1變量名稱2 類型2)2. 短變量聲明( := ) : 局部變量變量名稱 := 類型變量名稱1, 變量名稱2 := 類型1, 類型2變量聲明后沒有初始化,值為空變量需要聲明后才能使用,同一作用域不支持重復(fù)聲明
常量
-
聲明
const 常量名稱 = 值const (常量名稱1 = 值1常量名稱2 = 值2常量名稱3 (省略賦值則為上一個(gè) : 值二))常量聲明時(shí)必須賦值且不可改變
數(shù)據(jù)類型
-
整型
默認(rèn)為0int8(-128 - 127), int16, int32, int64uint8(0 - 255), uint16, uint32, uint64int類型轉(zhuǎn)換:int8(), int16(), int32(), int64()數(shù)字字面量語(yǔ)法:fmt.Printf("%d:10進(jìn)制輸出 %b:2進(jìn)制輸出 %o:8進(jìn)制輸出 %x:16進(jìn)制輸出") -
浮點(diǎn)型
默認(rèn)為0float32, float64fmt.Printf("%.nf:保留n位小數(shù)")精度丟失:第三方包(decimal)解決float 轉(zhuǎn) int:int()int 轉(zhuǎn) float:float32() -
布爾型
true, false(默認(rèn))不允許將整形強(qiáng)制轉(zhuǎn)換為布爾型布爾型無(wú)法參與數(shù)值運(yùn)算,也無(wú)法與其他類型進(jìn)行轉(zhuǎn)換 -
字符串
默認(rèn)為空: ""轉(zhuǎn)義字符: \r:回車符(返回行首) \n:換行符 \t:制表符 \':單引號(hào) \":雙引號(hào) \\: 斜杠多行字符串: ``常用操作:len(str): 求長(zhǎng)度+ 或 fmt.Sprint: 拼接字符串strings.Split: 切割strings.contains: 判斷是否包含strings.HasPrefix, strings.HasSuffix: 前綴、后綴判斷strings.Index(), strings.LastIndex(): 字串出現(xiàn)的位置strings.Join()其他類型 轉(zhuǎn) 字符串:fmt.Sprint()strconv -
byte&rune
byte: uint8,代表ASCII碼的一個(gè)字符rune: int32,代表一個(gè)UTF-8字符漢字占用3個(gè)字節(jié),字母占用一個(gè)字節(jié)遍歷字符串:for i := 0; i < len(str); i++ { //bytefmt.Println(str[i])}for _, i := range str { //runefmt.Println(i)} -
數(shù)組
數(shù)組的長(zhǎng)度必須是常量,并且長(zhǎng)度是數(shù)組的一部分,不能改變var 數(shù)組名 [n]類型var 數(shù)組名 [...]類型{值, 值, ...}var 數(shù)組名 [...]類型{索引值: 值, 索引值: 值, ...}遍歷:for i, v := range arr {// i 索引值, v 值}值類型:改變變量副本值的時(shí)候,不會(huì)改變變量本身的值引用類型:改變變量副本值的時(shí)候,會(huì)改變變量本身的值基本數(shù)據(jù)類型 和 數(shù)組都是值類型 -
切片
切片的長(zhǎng)度可以改變var 切片名 []類型[l:r]: 獲取切片值擴(kuò)容: append()復(fù)制切片(不影響原切片):copy()刪除: append([:n], [n:]...) 刪除索引為n修改: 轉(zhuǎn)換為byte或rune, 再進(jìn)行修改排序: sort -
map
無(wú)序 key: valuemake(map[類型]類型)map[類型]類型{key: value}遍歷:for k, v := range map {// k鍵, v 值}獲取: v, ok := map[key] //ok(true || false)刪除: delete(map, key)排序: 把key存入切片,將切片排序
運(yùn)算符
-
算術(shù)運(yùn)算符
+ - * / %(被除數(shù) - (被除數(shù)/除數(shù)) * 除數(shù))++、-- 是單獨(dú)的語(yǔ)句,并不是運(yùn)算符 -
關(guān)系運(yùn)算符
== != > < >= <= -
邏輯運(yùn)算符
&& || ! -
賦值運(yùn)算符
= += -= *= /= %=
流程控制
-
if else
if 表達(dá)式 {分支1} else if 表達(dá)式 {分支2} else {分支3} -
for
for 初始語(yǔ)句(可省略); 條件表達(dá)式; 結(jié)束語(yǔ)句(可省略) {循環(huán)體語(yǔ)句} -
switch
switch expression {case condition: 語(yǔ)句 break(可以不寫)case condition1, condition2: 語(yǔ)句 breakdefauit: 語(yǔ)句 } -
break&continue
label1:for xxx {for yyy {break label1 //跳出label1continue label1 //結(jié)束本次label1}} -
goto
goto label1xxxlabel1:yyygoto跳轉(zhuǎn)到label1
函數(shù)
-
定義
func 函數(shù)名 (參數(shù) 類型, 可變參數(shù) ...類型) (返回值 類型){函數(shù)體}返回值命名: 函數(shù)定義時(shí)可以給返回值命名,并在函數(shù)體中直接使用這些變量,最后通過(guò)return返回 -
類型與匿名函數(shù)
type 函數(shù)類型名 func(參數(shù) 類型) 返回值匿名自執(zhí)行函數(shù): func(參數(shù)) 返回值{} (參數(shù)) -
閉包
全局變量特點(diǎn): 常駐內(nèi)存,污染全局局部變量特點(diǎn): 不常駐內(nèi)存,不污染全局閉包: 常駐內(nèi)存,不污染全局func 函數(shù)名() func() 類型 {return func() (返回值 類型) {return}} -
defer
defer 會(huì)將其后面跟隨的語(yǔ)句進(jìn)行延遲處理,return之前逆序執(zhí)行(最后的語(yǔ)句,最先執(zhí)行)return x: 1. 返回值 = x 2. 運(yùn)行defer3. RET指令 -
panic & recover
panic(): 可以在任何地方拋出異常recover(): 只能在defer調(diào)用的函數(shù)中接收異常 panic("err")defer func() {err := recover()}
指針
指針是一個(gè)變量,存儲(chǔ)另一個(gè)變量的內(nèi)存地址 定義: &變量 取值: *變量結(jié)構(gòu)體
type 類型名 struct {字段名 字段類型 }結(jié)構(gòu)體函數(shù):type Fxm intfunc (Fxm) 函數(shù)名() {}匿名字段: 聲明時(shí)沒有字段名只有類型(同種類型的匿名字段只有一個(gè))結(jié)構(gòu)體的類型是指針、切片、map時(shí),如要使用,需要先makejson轉(zhuǎn)換:jsonByte := json.Marshal() (私有變量不能被json包訪問(wèn)) (生成字節(jié)切片)jsonStr := string(jsonByte)結(jié)構(gòu)體標(biāo)簽:type Fxm struct {Id int `json:"id"`}接口
type 接口名 interface {方法名(參數(shù)) 返回值 }空接口: 接口中不定義任何方法,可以表示任意數(shù)據(jù)類型 map的值、切片可以是空接口類型類型斷言: (.(type)只能結(jié)合switch使用)switch v := interface1.(type) {case string: xxx}值接收者: 實(shí)例化后的結(jié)構(gòu)體值類型和結(jié)構(gòu)體指針類型都可以賦值給接口變量 指針接收者: 實(shí)例化后的結(jié)構(gòu)體指針類型可以賦值給接口變量,結(jié)構(gòu)體值類型不可并發(fā)&并行
-
協(xié)程
goroutine: go 函數(shù)名等待goroutine執(zhí)行完畢:var wg = sync.WaitGroupwg.Add(1) //協(xié)程計(jì)數(shù)器加1wg.Done(1) //協(xié)程計(jì)數(shù)器加-1wg.Wait() //等待協(xié)程執(zhí)行完畢獲取當(dāng)前計(jì)算機(jī)cpu個(gè)數(shù)runtime.NumCPU()設(shè)置使用cpu個(gè)數(shù)runtime.GoMAXPROCS(cpu個(gè)數(shù)) -
管道Channel
管道是goroutine之間的通訊方式,先入先出Golang 的并發(fā)模型是CSP,提倡通過(guò)通信共享內(nèi)存,而不是通過(guò)內(nèi)存實(shí)現(xiàn)通信 -
channel
channel是一種引用類型聲明: var 變量名 chan 類型管道聲明后需要make初始化之后才能使用make(chan 類型, 容量)管道的發(fā)送和接收使用 <-發(fā)送: channel1 <- 值接收: 值 := <- channel1關(guān)閉: close(channel1)遍歷管道: for(管道沒有key) -
單向管道
默認(rèn)是雙向只寫: make(chan<- 類型, 容量)只讀: make(<-chan 類型, 容量) -
多路復(fù)用 select
同時(shí)從多個(gè)管道獲取數(shù)據(jù),不需要關(guān)閉管道select{case 值 := <- channel1: xxxcase channel2 <- 值: xxxdefault: xxx} -
互斥鎖
sync.Mutex: Lock() Unlock() -
讀寫互斥鎖
可以讓多個(gè)讀操作并發(fā),但寫操作是互斥的sync.RWMutex寫操作: Lock() Unlock()讀操作: RLock() RUnlock()
反射
需求: 一個(gè)函數(shù)有能力統(tǒng)一處理各種值類型,而這些類型可能無(wú)法共享同一個(gè)接口,可能這個(gè)類型不存在 反射: 在程序運(yùn)行期間對(duì)程序本身進(jìn)行訪問(wèn)和修改的能力 支持反射的語(yǔ)言可以在程序編譯期將變量的反射信息整合到可執(zhí)行文件,并給程序提供接口訪問(wèn)反射信息-
reflect
Go中的變量分為兩部分: 類型信息、值信息reflect.TypeOf() //Name、Kindreflect.ValueOf()修改: Elem().Setxxx()
文件
-
讀取文件:
file, err := os.Open(文件名) //只讀defer file.Close()file.Read()file, err := os.Open(文件名) //只讀defer file.Close()reader := bufio.NewReader(file)line, err := reader.ReadString('\n')ioutil.ReadFile(文件名) -
寫入文件:
file, err := os.OpenFile(文件名, os.O_CREATE|os.O_RDWR, 0666)defer file.Close()file.Write([]byte(str))file.WriteString(str)file, err := os.OpenFile(文件名, os.O_CREATE|os.O_RDWR, 0666)defer file.Close()writer := bufio.NewWriter(file)writer.WriteString(str)writer.Flush()ioutil.WriteFile(文件名, []byte(str), 0666) -
文件操作:
文件重命名: os.Rename(原文件名,文件名)復(fù)制文件: file, err := ioutil.ReadFile(原文件)ioutil.WriteFile(文件名, file, 0644)創(chuàng)建目錄:os.Mkdir(目錄名, 0666)刪除目錄和文件:os.Remove(文件名)os.RemoveAll(目錄名)
其他
-
查看環(huán)境變量
go env -
設(shè)置GOPROXY代理
go env -w GOPROXY=https://goproxy.io,direct -
更新go.sum
go mod tidy -
下載第三方包
1. go get 包名(全局,不建議) 2. go mod download(全局,建議) 3. go mod vendor(下載到項(xiàng)目中) -
定時(shí)器
time.NewTicker()time.Slwwp() -
初始化項(xiàng)目
go mod init 項(xiàng)目名() -
大小寫:
首字母小寫:私有變量、私有方法首字母大寫:公有變量、公有方法 -
導(dǎo)入
import 別名 包名import _ 包名:匿名引入 -
init
最先執(zhí)行最后導(dǎo)入包的init -
第三方包網(wǎng)站
https://pkg.go.dev/
小問(wèn)題
-
main.go 導(dǎo)包找不到
如下圖片添加:https://goproxy.io
總結(jié)
- 上一篇: 什么是银行一类账户和二类账户?银行的一类
- 下一篇: 【HDU - 4509】湫湫系列故事——