我在玩通道。我有下面这段代码,其中包含一个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
你应该先看看golang tour。https:/tour.golang.orgconcurrency4
你在同一时间使用两种不同的读取方式。for range c
从c通道读一次,然后你再从通道中读一次,用的是 <-c
如果你想写出你发送到通道的内容,只需使用下面的一个方法。
for value := range c {
fmt.Println(value)
}
OR
for {
select {
case value, ok := <- c:
if !ok {
return
}
fmt.Println(value)
}
}
因为你有奇数的迭代(1...5),最后的0出现是因为从封闭的通道中读取的(类型的默认值).
如果你使用 value, ok := <-c
而当你从它那里读取时,通道是关闭的,该值将始终是默认值,并且 ok
将是 false
.
因为range从通道中取值,正确的代码应该是这样的。
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 value := range c {
fmt.Println(value)
}
}
你的罪魁祸首是 range c
https:/play.golang.orgpyGrUhdLAQE-。
你不应该做的范围上 c
相反,你应该使用无限for循环或case语句。
func main() {
c := make(chan int)
go send(c)
for {
d, ok:= <- c
if !ok{
break
}
fmt.Println(d)
}
}
如果你真的想使用range over c
那么你应该这样做
func main() {
c := make(chan int)
go send(c)
for x := range c {
fmt.Println(x)
}
}