使用 range 来循环通道,为什么在接收到所有值之前就终止了?

问题描述 投票:0回答:0

此代码是《The Go 编程语言》一书第 8.4 节中程序的修改版本。

package main

import (
"fmt"
)

func main() {
naturals := make(chan int)
squares := make(chan int)
done := make(chan struct{})

    // counter
    go func() {
        for x := 0; x <= 10; x++ {
            naturals <- x
        }
        done <- struct{}{}
    }()
    
    // squarer
    go func() {
        for x := range naturals {
            squares <- x * x
        }
        close(squares)
    }()
    
    // printer
    go func() {
        for x := range squares {
            fmt.Println(x)
        }
    }()
    
    <-done
    naturals <- 90
    
    close(naturals)

}

当我运行此命令时,我得到输出:

0 1 4 9 16 25 36 49 64 81 100

但是当我将最后几行更改为:

naturals <- 90
<-done

我得到输出:

8100 0 1 4 9 16 25 36 49 64 81

在第一种情况下,当

<-done
naturals <- 90
之前时,我期望它打印数字0到10的所有平方,然后打印90的平方,然后关闭通道并结束程序。

在第二种情况下,当

naturals <- 90
<-done
之前时,我预计 8100 会打印在 0 到 10 的平方之前的某个位置,但我也预计所有这些都会被打印。

有人可以帮助我了解正在发生的事情吗?

go concurrency channel goroutine
© www.soinside.com 2019 - 2024. All rights reserved.