在 for 循环中写入通道会跳过迭代
writing to channel in for loop skips iterations
我正在玩频道。我在下面有这段代码,其中包含一个 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
你的罪魁祸首是 range c
https://play.golang.org/p/yGrUhdLAQE-
您不应在 c
上执行范围,而应使用无限循环或 case 语句。
func main() {
c := make(chan int)
go send(c)
for {
d, ok:= <- c
if !ok{
break
}
fmt.Println(d)
}
}
不过如果你真的想在 c
上使用范围,那么你应该这样做
func main() {
c := make(chan int)
go send(c)
for x := range c {
fmt.Println(x)
}
}
因为范围从通道中获取一个值,正确的代码应该是这样的
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)
}
}
你应该先看看 golang 之旅。
https://tour.golang.org/concurrency/4
您同时使用两种不同的阅读方式:
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
。
我正在玩频道。我在下面有这段代码,其中包含一个 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
你的罪魁祸首是 range c
https://play.golang.org/p/yGrUhdLAQE-
您不应在 c
上执行范围,而应使用无限循环或 case 语句。
func main() {
c := make(chan int)
go send(c)
for {
d, ok:= <- c
if !ok{
break
}
fmt.Println(d)
}
}
不过如果你真的想在 c
上使用范围,那么你应该这样做
func main() {
c := make(chan int)
go send(c)
for x := range c {
fmt.Println(x)
}
}
因为范围从通道中获取一个值,正确的代码应该是这样的
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)
}
}
你应该先看看 golang 之旅。 https://tour.golang.org/concurrency/4
您同时使用两种不同的阅读方式:
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
。