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