3 回答

TA贡献1852条经验 获得超7个赞
1-当您处理一个频道时,可以使用for,
考虑这个工作代码(The Go Playground):
package main
import "fmt"
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
close(ch)
for range ch {
}
fmt.Println("Done.")
}
这将清空通道。
注意:您应该close使用通道或使用break语句来完成该循环。
2- 当您处理更多可能使用的频道时select,就像这样(The Go Playground):
for {
select {
case <-pause:
fmt.Println("pause")
select {
case <-play:
fmt.Println("play")
case <-quit:
wg.Done()
return
}
case <-quit:
wg.Done()
return
default:
work()
}
}
3- 使用 nil 和封闭通道(The Go Playground):
package main
import "fmt"
func main() {
var quit chan struct{} // nil
select {
case <-quit:
fmt.Println("1")
default:
fmt.Println("2") // This runs
}
quit = make(chan struct{}, 1)
select {
case <-quit:
fmt.Println("10")
default:
fmt.Println("20") // This runs
}
quit <- struct{}{} // send
select {
case <-quit:
fmt.Println("100") // This runs
default:
fmt.Println("200")
}
close(quit)
select {
case <-quit:
fmt.Println("1000") // This runs
default:
fmt.Println("2000")
}
select {
case <-quit:
fmt.Println("10000") // This runs
default:
fmt.Println("20000")
}
}
输出:
2
20
100
1000
10000
选择语句
“选择”语句选择一组可能的发送或接收操作中的哪一个将继续。它看起来类似于“switch”语句,但所有案例都涉及通信操作。
具有 RecvStmt 的案例可以将 RecvExpr 的结果分配给一个或两个变量,这些变量可以使用短变量声明来声明。RecvExpr 必须是(可能带括号的)接收操作。最多可以有一个默认案例,它可能出现在案例列表中的任何位置。
“select”语句的执行分几个步骤进行:
对于语句中的所有情况,在输入“select”语句时,接收操作的通道操作数以及发送语句的通道和右侧表达式仅按源顺序计算一次。结果是一组要接收或发送到的通道,以及要发送的相应值。无论选择哪种(如果有)通信操作进行,该评估中的任何副作用都会发生。RecvStmt 左侧的带有短变量声明或赋值的表达式尚未计算。如果一个或多个通信可以进行,则通过统一的伪随机选择选择一个可以进行的通信。否则,如果存在默认情况,则选择该情况。如果没有默认情况,则“选择” 语句块,直到至少有一个通信可以进行。除非所选案例是默认案例,否则执行相应的通信操作。如果所选用例是带有短变量声明或赋值的 RecvStmt,则计算左侧表达式并分配接收到的值(或多个值)。执行所选案例的语句列表。由于 nil 通道上的通信永远无法进行,因此只有 nil 通道且没有默认案例的选择会永远阻塞。执行所选案例的语句列表。由于 nil 通道上的通信永远无法进行,因此只有 nil 通道且没有默认案例的选择会永远阻塞。执行所选案例的语句列表。由于 nil 通道上的通信永远无法进行,因此只有 nil 通道且没有默认案例的选择会永远阻塞。

TA贡献1827条经验 获得超8个赞
在您的情况下,似乎一个简单的循环就足够了:
for _ = range ch { fmt.Println("drain")}
如果您有多个goroutines 需要处理,则 Select 是必需的。巡回赛有一个range 和 close的例子。
另一种情况select
是幂等通道关闭: https: //play.golang.org/p/_Ol42BvuuS。

TA贡献1887条经验 获得超5个赞
如果 select 中只有一种情况,那么最好use for range instead of for { select {} } (gosimple)
使用S1000
golint 检查。
for range
代码就像:
for range ch { fmt.Println("here")}
- 3 回答
- 0 关注
- 481 浏览
添加回答
举报