go學習4
go學習4
接上一篇通道
關閉通道
語法:close(ch)
ch為通道名
接收方可以用ok
來檢查通道是否關閉
語法:v,ok := <-ch
從關閉的通道讀取到的值會是該通道型別的零值。例如,當通道是一個 int 型別的通道時,那麼從關閉的通道讀取的值將會是 0。
可以用for range
迴圈從通道 ch 接收資料,直到該通道關閉。一旦關閉了 ch,迴圈會自動結束。
緩衝通道
可以建立一個有緩衝(Buffer)的通道。只在緩衝已滿的情況,才會阻塞向緩衝通道傳送資料。同樣,只有在緩衝為空的時候,才會阻塞從緩衝通道接收資料。
語法:ch := make(chan type, capacity)
capacity 指定緩衝的大小,可以理解為緩衝的容量
capacity 應該大於 0,無緩衝通道的容量預設為 0,忽略不寫。
cap(ch)
為ch緩衝通道的容量 len(ch)
為ch緩衝通道的長度,就是當前通道中還未讀取的個數
select
和switch
的語法類似,不同的是 select裡的每個case 都是針對通道的操作。
select 語句用於在多個傳送/接收通道操作中進行選擇。select 語句會一直阻塞,直到傳送/接收操作準備就緒。如果有多個通道操作準備完畢,select 會隨機地選取其中之一執行。(PS:說白了 就是先接收的誰的就用誰的 ,後來的都不管了,可以用default防止一直阻塞
工作池(Worker PoolPools)
用WaitGroup
實現工作池,用來等待一批Go協程執行結束,會控制程式一直處於阻塞的狀態,直到這些協程全部執行完畢。
語法:需要引入sync
包
package main
import (
"fmt"
"sync"
"time"
)
func process(i int, wg *sync.WaitGroup) {
fmt.Println("started", i)
time.Sleep(2 * time.Second)//阻塞兩秒
fmt.Printf("end", i)
wg.Done() //每執行一次,就會在計數器上減1
}
func main() {
no := 3
var wg sync.WaitGroup
for i := 0; i < no; i++ {
wg.Add(1) //每執行一次,就會在計數器上加1
go process(i, &wg) //這裡必須傳入地址型別,不然主程式無法知道協程執行結束
}
wg.Wait() //確保Go主協程的計數器為0,解除阻塞
fmt.Println("All end")
}
defer
含有 defer 語句的函式或方法,會在該函式將要返回之前,呼叫另一個函式(ps:有點PHP解構函式的意思)
語法:defer 函式名
注意:在 Go 語言中,並非在呼叫defer函式的時候才確定實參,而是當執行 defer 語句的時候,就會對延遲函式的實參進行求值
defer棧
當一個函式內多次呼叫 defer 時,Go 會把 defer 呼叫放入到一個棧中,隨後按照後進先出的順序執行。
strings包
HasPrefix 判斷字串 s 是否以 prefix 開頭:
方法:strings.HasPrefix(s, prefix string) bool
HasSuffix 判斷字串 s 是否以 suffix 結尾:
方法:strings.HasSuffix(s, suffix string) bool
判斷字串a 中是否包含子串b
方法:Contains(s, substr string) bool
判斷字串s是否包含字串chars中的任一字元
方法:ContainsAny(s, chars string) bool
返回字串s中有幾個不重複的sep子串
方法:Count(s, sep string) int
子串sep在字串s中第一次出現的位置,不存在則返回-1
方法:Index(s, sep string) int
子串sep在字串s中最後一次出現的位置,不存在則返回-1
方法:LastIndex(s, sep string) int
字元c在s中第一次出現的位置,不存在則返回-1
方法:IndexByte(s string, c byte) int
返回將所有字母都轉為對應的小寫版本的拷貝
方法:ToLower(s string) string
返回將所有字母都轉為對應的大寫版本的拷貝
方法:ToUpper(s string) string
返回將s中前n個不重疊old子串都替換為new的新字串,如果n<0會替換所有old子串
方法:Replace(s, old, new string, n int) string
用去掉s中出現的sep的方式進行分割,會分割到結尾,並返回生成的所有片段組成的切片(每一個sep都會進行一次切割,即使兩個sep相鄰,也會進行兩次切割)。如果sep為空字元,Split會將s切分成每一個unicode碼值一個字串
方法:Split(s, sep string) []string
效果同上,多了一個可以控制返回的數量n=0 返回nil,n<0 返回所有
方法:SplitN(s, sep string, n int) []string
將一系列字串連線為一個字串,之間用sep來分隔
方法:Join(a []string, sep string) string
刪除s頭部的prefix字串。如果s不是以prefix開頭,則返回原始s。
方法:TrimPrefix(s, prefix string) string
刪除s尾部的suffix字串。如果s不是以suffix結尾,則返回原始s。
方法:TrimSuffix(s, suffix string) string
time包
獲取當前時間戳
time.Now().Unix()
獲取當前日期
time.Now().Format("2006-01-02 15:04:05")
Format(“2006-01-02 15:04:05”)是固定寫法,據說2006-01-02 15:04:05是go誕生的時間,可以根據format內的時間長短來控制返回的資訊長短
時間戳轉日期格式
time.Unix(1389058332,0).Format("2006-01-02 15:04:05")
日期格式轉時間戳
time.Parse("2016-01-02 15:04:05","2018-08-30 17:48:00")