go語(yǔ)言使用range來(lái)接收通道里面的數(shù)據(jù)
在 Go 語(yǔ)言中,可以使用 for ... range 循環(huán)來(lái)遍歷通道(channel)。for ... range 循環(huán)會(huì)一直從通道中接收值,直到通道關(guān)閉并且所有值都被接收完畢。
使用 for ... range 遍歷通道
示例代碼
下面是一個(gè)使用 for ... range 遍歷通道的示例:
package main
import (
"fmt"
"time"
)
func main() {
// 創(chuàng)建一個(gè)有緩沖的通道
ch := make(chan int, 5)
// 啟動(dòng)一個(gè) goroutine 向通道發(fā)送值
go func() {
for i := 0; i < 5; i++ {
ch <- i
time.Sleep(100 * time.Millisecond) // 模擬耗時(shí)操作
}
close(ch) // 關(guān)閉通道
}()
// 使用 for ... range 遍歷通道
for value := range ch {
fmt.Println("Received:", value)
}
}

解釋
創(chuàng)建通道:
ch := make(chan int, 5)
make(chan int, 5)創(chuàng)建一個(gè)容量為 5 的有緩沖通道。
啟動(dòng) goroutine 發(fā)送值:
go func() {
for i := 0; i < 5; i++ {
ch <- i
time.Sleep(100 * time.Millisecond) // 模擬耗時(shí)操作
}
close(ch) // 關(guān)閉通道
}()
- 啟動(dòng)一個(gè) goroutine,向通道發(fā)送 0 到 4 的整數(shù)。
time.Sleep(100 * time.Millisecond)模擬耗時(shí)操作,使發(fā)送操作之間有時(shí)間間隔。close(ch)關(guān)閉通道,表示不再發(fā)送新的值。
使用 for ... range 遍歷通道:
for value := range ch {
fmt.Println("Received:", value)
}
for value := range ch循環(huán)會(huì)一直從通道中接收值,直到通道關(guān)閉并且所有值都被接收完畢。- 每次接收到一個(gè)值,都會(huì)打印出來(lái)。
注意事項(xiàng)
關(guān)閉通道:
- 必須在發(fā)送完所有值后關(guān)閉通道,否則
for ... range循環(huán)會(huì)一直阻塞,等待新的值。 - 關(guān)閉通道后,不能再向通道發(fā)送值,否則會(huì)引發(fā) panic。
- 必須在發(fā)送完所有值后關(guān)閉通道,否則
多接收者:
- 如果有多個(gè) goroutine 同時(shí)從同一個(gè)通道接收值,可能會(huì)出現(xiàn)競(jìng)爭(zhēng)條件。建議使用互斥鎖或其他同步機(jī)制來(lái)確保線程安全。
空通道:
- 對(duì)于無(wú)緩沖通道,如果沒(méi)有接收者,發(fā)送操作會(huì)阻塞,直到有接收者準(zhǔn)備接收值。
示例:多接收者
下面是一個(gè)多接收者從同一個(gè)通道接收值的示例:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
// 創(chuàng)建一個(gè)有緩沖的通道
ch := make(chan int, 5)
// 啟動(dòng)一個(gè) goroutine 向通道發(fā)送值
go func() {
for i := 0; i < 5; i++ {
ch <- i
time.Sleep(100 * time.Millisecond) // 模擬耗時(shí)操作
}
close(ch) // 關(guān)閉通道
}()
// 使用 sync.WaitGroup 等待所有接收者完成
var wg sync.WaitGroup
// 啟動(dòng)多個(gè)接收者 goroutine
for i := 0; i < 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for value := range ch {
fmt.Printf("Receiver %d received: %d\n", id, value)
}
}(i)
}
// 等待所有接收者完成
wg.Wait()
}
解釋
啟動(dòng)多個(gè)接收者 goroutine:
for i := 0; i < 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for value := range ch {
fmt.Printf("Receiver %d received: %d\n", id, value)
}
}(i)
}
- 啟動(dòng)三個(gè)接收者 goroutine,每個(gè) goroutine 都使用
for ... range循環(huán)從通道中接收值。 wg.Add(1)增加 WaitGroup 的計(jì)數(shù)。defer wg.Done()在 goroutine 結(jié)束時(shí)減少 WaitGroup 的計(jì)數(shù)。
等待所有接收者完成:
wg.Wait()
- 使用
wg.Wait()等待所有接收者 goroutine 完成。
通過(guò)使用 for ... range 循環(huán),可以方便地遍歷通道中的值,直到通道關(guān)閉并且所有值都被接收完畢。這對(duì)于處理并發(fā)任務(wù)和數(shù)據(jù)流非常有用。
到此這篇關(guān)于go語(yǔ)言使用range來(lái)接收通道里面的數(shù)據(jù)的文章就介紹到這了,更多相關(guān)go語(yǔ)言range接收數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解如何解決golang定時(shí)器引發(fā)的id重復(fù)問(wèn)題
這篇文章主要為大家詳細(xì)介紹了如何解決golang定時(shí)器引發(fā)的id重復(fù)問(wèn)題,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04
GoLang BoltDB數(shù)據(jù)庫(kù)詳解
這篇文章主要介紹了GoLang BoltDB數(shù)據(jù)庫(kù),boltdb是使用Go語(yǔ)言編寫的開(kāi)源的鍵值對(duì)數(shù)據(jù)庫(kù),boltdb存儲(chǔ)數(shù)據(jù)時(shí) key和value都要求是字節(jié)數(shù)據(jù),此處需要使用到 序列化和反序列化2023-02-02
Go單元測(cè)試對(duì)GORM進(jìn)行Mock測(cè)試
這篇文章主要為大家介紹了Go單元測(cè)試對(duì)GORM進(jìn)行Mock測(cè)試用例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
Golang?Gin框架獲取請(qǐng)求參數(shù)的幾種常見(jiàn)方式
在我們平常添加路由處理函數(shù)之后,就可以在路由處理函數(shù)中編寫業(yè)務(wù)處理代碼了,但在此之前我們往往需要獲取請(qǐng)求參數(shù),本文就詳細(xì)的講解下gin獲取請(qǐng)求參數(shù)常見(jiàn)的幾種方式,需要的朋友可以參考下2024-02-02
詳解Go并發(fā)編程時(shí)如何避免發(fā)生競(jìng)態(tài)條件和數(shù)據(jù)競(jìng)爭(zhēng)
大家都知道,Go是一種支持并發(fā)編程的編程語(yǔ)言,但并發(fā)編程也是比較復(fù)雜和容易出錯(cuò)的。比如本篇分享的問(wèn)題:競(jìng)態(tài)條件和數(shù)據(jù)競(jìng)爭(zhēng)的問(wèn)題2023-04-04

