這個要解決的問題是,比如如果有一個大回圈,取自一個大的檔案,要進行邏輯處理,那么這個邏輯的代碼要放在回圈每一行的回圈體里面,這樣有可能會出現一個for回圈的邏輯嵌套,一層又一層,類似俄羅斯套娃.如果放在外面那么就需要把大回圈的每一行資料存到一個陣列或者切片里面,這樣會占很大的記憶體
那么就可以使用這種技巧來既能解決回圈嵌套,又能解決不存在占用大記憶體的資料
創建一個channel,開啟一個goroutine,在groutine里面進行for回圈遍歷,把每一行的資料發送到channel中
在主groutine里面,讀取channel,因為接收者總是比發送者先執行,那么這個地方就會阻塞等待那一個資料到來
這樣就形成這樣一個良性的同步操作,雖然是在不同的groutine里面執行的,但是總是同步執行的,并且解決了回圈嵌套的問題
package mainimport "fmt"import "time"func main() { arr := []int{1, 2, 3, 4, 5, 6} yields := make(chan int) go func() { for _, i := range arr { //每次這里先列印,然后跳到回圈外 fmt.Println("回圈內", i) yields <- i //這是防止執行太快看不到效果 time.Sleep(time.Second) } close(yields) }() for i := range yields { fmt.Println("回圈外:", i) }}
就是這樣的效果
回圈內 1回圈外: 1回圈內 2回圈外: 2回圈內 3回圈外: 3回圈內 4回圈外: 4回圈內 5回圈外: 5回圈內 6回圈外: 6
如果那個channel是個有快取的channel,就會先把快取數量的全都塞進channel,后回圈外才執行,這個在很多的案例里都有使用
yields := make(chan int, 6)回圈內 1回圈內 2回圈內 3回圈內 4回圈內 5回圈內 6回圈外: 1回圈外: 2回圈外: 3回圈外: 4回圈外: 5回圈外: 6
比如說這樣的代碼:
mailboxes := make(chan *imap.MailboxInfo, 20) go func() { imapClient.List("", "*", mailboxes) }() //列取郵件夾 for m := range mailboxes { mailDirs = append(mailDirs, m.Name) }
這個很像是PHP中的yield的作用,溝通函式內外
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/59784.html
標籤:Go
上一篇:go-redis
