select是Go中的一个控制结构,类似于用于通信的switch语句。每个case必须是一个通信操作,要么是发送要么是接收。 select随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。一个默认的子句应该总是可运行的。
package main
import "fmt"
func main() {
var c1, c2, c3 chan int
var i1, i2 int
select {
case i1 = <-c1:
fmt.Printf("received ", i1, " from c1\n")
case c2 <- i2:
fmt.Printf("sent ", i2, " to c2\n")
case i3, ok := (<-c3): // same as: i3, ok := <-c3
if ok {
fmt.Printf("received ", i3, " from c3\n")
} else {
fmt.Printf("c3 is closed\n")
}
default:
fmt.Printf("no communication\n")
}
}
输出:no communication
为什么输出no communication而不是sent i2 to c2 呢
原因:goroutine 1 [chan send (nil chan)]:
go中的channel定义之后,必须要初始化
package main
import "fmt"
func main() {
c := make(chan int)
select {
case c <- 10: // c中放入了10,因为chan的buffer为1
default:
fmt.Printf("no communication")
}
}
输出:no communication
package main
import "fmt"
func main() {
c := make(chan int,1)
select {
case c <- 10: // c中放入了10,因为chan的buffer为1
fmt.Printf("succeed")
default:
fmt.Printf("no communication")
}
}
输出:succeed
总结:channel一定要用make初始话,且必须要加初始化容量,默认为0,。