【发布时间】:2018-05-20 07:49:33
【问题描述】:
鉴于此代码使用扇入模式模拟为 3 个 URL 获取一些网站内容,并在压缩通道上进行范围:https://play.golang.org/p/MSkRI7x4vz
for s := range r {
println(s)
}
这很好用,但我想使用整体超时信号通道,所以我尝试在 for 循环中使用 select,如下所示: https://play.golang.org/p/LjDoIc0j-z
totalTimeout := time.After(300 * time.Millisecond)
loop:
for {
select {
case s := <-r:
fmt.Println(s)
case <-totalTimeout: // signaling usage of a channel
fmt.Println("Timed out")
break loop
}
}
}
这表现不好:输入通道关闭后,来自扇入的压缩通道关闭。但是现在读取零值,直到超时有效发生。当我阅读http://www.tapirgames.com/blog/golang-channel 或规范https://golang.org/ref/spec#Close 时,似乎从封闭通道接收“永不阻塞”,因此返回零值。我只能猜测,一个范围检测到关闭,而选择不能,因为它的条件是从通道本身读取。
我可以这样爆发
case s := <-r:
if s == "" {
break loop
}
fmt.Println(s)
是否有另一种方法可以停止获取空值,或者这是在 for 循环中使用 select 的正确惯用方式?
【问题讨论】:
-
接收(可以)返回两个值。使用第二个。