Golang 中保存通道的 map 在设为 nil 后不会回收元素,即通道依然有效

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 的同时关闭所有通道,则应先主动关闭通道。

你可能感兴趣的:(Golang 中保存通道的 map 在设为 nil 后不会回收元素,即通道依然有效)