Golang 中,如果用一個 map 保存實例化的通道,並用在協程間發送和接收。當該 map 被賦值為 nil 時,管理的通道依然有效。
示例代碼如下:
package main
import (
"fmt"
"time"
)
func main() {
// 創建一個map用於保存通道
channelMap := make(map[string]chan int)
// 插入初始化的通道
channelMap["ch1"] = make(chan int)
channelMap["ch2"] = make(chan int)
// 使用WaitGroup等待兩個協程完成
//var wg sync.WaitGroup
//wg.Add(2)
// 啓動發送協程
go sendToChannel(channelMap["ch1"])
// 啓動監聽協程
go listenToChannel(channelMap["ch1"])
// 等待協程完成
//wg.Wait()
time.Sleep(2 * time.Second)
// 將map設為nil
channelMap = nil
fmt.Println("channelMap is assigned nil")
// 等待一段時間以確保觀察效果
time.Sleep(2 * time.Second)
}
func sendToChannel(ch chan int) {
// 發送數據到通道
for i := 1; i <= 10; i++ {
ch <- i
time.Sleep(time.Millisecond * 500) // 模擬發送間隔
}
// 關閉通道
//close(ch)
}
func listenToChannel(ch chan int) {
// 監聽通道
for {
select {
case value, ok := <-ch:
if !ok {
fmt.Println("Channel closed.")
return
}
fmt.Println("Received:", value)
}
}
}
你也可以訪問如下鏈接嘗試效果:
https://go.dev/play/p/BECnO6KY-7F
實際執行結果為:
Received: 1
Received: 2
Received: 3
Received: 4
Received: 5
channelMap is assigned nil
Received: 6
Received: 7
Received: 8
Received: 9
從執行結果可以看出,雖然 channelMap 被賦值為 nil,但這並不意味着其值會被立即回收。如果 map 的元素是通道,則通道會始終有效。
如果想在銷燬 map 的同時關閉所有通道,則應先主動關閉通道。