douchui4815 2018-07-02 13:13
浏览 24
已采纳

侦听频道并进行循环处理时重写频道

While trying few experiments in channels, I came up with below code:

var strChannel = make(chan string, 30)
var mutex = &sync.Mutex{}

func main() {

    go sampleRoutine()

    for i := 0; i < 10; i++ {
        mutex.Lock()
        strChannel <- strconv.FormatInt(int64(i), 10)
        mutex.Unlock()
        time.Sleep(1 * time.Second)
    }

    time.Sleep(10 * time.Second)
}

func sampleRoutine() {
/*  A: for msg := range strChannel{*/
/*  B: for {
        msg := <-strChannel*/
        log.Println("got message ", msg, strChannel)
        if msg == "3" {
            mutex.Lock()
            strChannel = make(chan string, 20)
            mutex.Unlock()
        }
    }
}

Basically here while listening to a given channel, I am assigning the channel variable to a new channel in a specific condition (here when msg == 3).

When I use the code in comment block B it works as expected, i.e. the loop moves on to the newly created channel and prints 4-10.

However comment block A which I believe is just a different way to write the loop doesn't work i.e. after printing "3" it stops.

Could someone please let me know the reason for this behavior?

And also is code like this where a routine listening on a channel, creating a new one safe?

  • 写回答

2条回答 默认 最新

  • duan198727 2018-07-02 14:02
    关注

    In Go, for statement evaluate the value on the right side of range before the loop begins.

    That means changing the value of the variable on the right side of range will take no effects. So in your code, in Variant A, msg is ever-iterating over the orignal channel and never changed. In Varaint B, it works as intended as the channel is being evaluated per iteration.

    The concept is a little bit tricky. It does not mean you cannot modify items of the slice or map on the right side of range. If you look deeper into it, you will find that in Go, map and slice stores a pointer, and modify its item does not change that pointer, so it has effects.

    It is even more trickier in case of array. Modifying item of an array on the right side of range has no effects. This is due to Go's mechanism about storing array as a value.

    Playground examples: https://play.golang.org/p/wzPfGHFYrnv

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据