在 for 循环中写入通道会跳过迭代

我正在玩频道。我在下面有这段代码,其中包含一个 for 循环。我不明白为什么程序似乎跳过了所有其他迭代,以及为什么最后一个值为 0。


package main


import (

    "fmt"

    "time"

)


func send(c chan int) {

    for i := 1; i < 6; i++ {

        time.Sleep(time.Second)

        c <- i

    }

    close(c)

}


func main() {

    c := make(chan int)

    go send(c)

    for range c {

        fmt.Println(<-c)

    }

}

输出:


2

4

0


千巷猫影
浏览 120回答 3
3回答

动漫人物

因为 range 从通道中获取一个值,所以正确的代码看起来像这样package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "time")func send(c chan int) {&nbsp; &nbsp; for i := 1; i < 6; i++ {&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(time.Second)&nbsp; &nbsp; &nbsp; &nbsp; c <- i&nbsp; &nbsp; }&nbsp; &nbsp; close(c)}func main() {&nbsp; &nbsp; c := make(chan int)&nbsp; &nbsp; go send(c)&nbsp; &nbsp; for value := range c {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(value)&nbsp; &nbsp; }}

繁星淼淼

您应该先查看 golang 之旅。 https://tour.golang.org/concurrency/4您同时使用两种不同的读取方式:for range c从 c 通道读取一次,然后再次从通道读取<-c如果您想写出您发送到频道的内容,只需使用以下选项之一:for value := range c {&nbsp; fmt.Println(value)}ORfor {&nbsp; select {&nbsp; case value, ok := <- c:&nbsp; &nbsp; if !ok {&nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println(value)&nbsp; }}因为您有奇数次迭代(1..5),所以最后一个 0 出现是因为从封闭通道读取(类型的默认值)。如果您使用value, ok := <-c并且在读取时通道已关闭,则该值将始终为默认值,并且ok将为false.

摇曳的蔷薇

你的罪魁祸首是range chttps://play.golang.org/p/yGrUhdLAQE-您不应该使用 range onc而是应该使用无限 for 循环或 case 语句。func main() {&nbsp; &nbsp; c := make(chan int)&nbsp; &nbsp; go send(c)&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; d, ok:= <- c&nbsp; &nbsp; &nbsp; &nbsp; if !ok{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(d)&nbsp; &nbsp; }}虽然如果你真的想使用 range overc那么你应该做这样的事情func main() {&nbsp; &nbsp; c := make(chan int)&nbsp; &nbsp; go send(c)&nbsp; &nbsp; for x := range c {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(x)&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go