channel
channel用于协程(goroutine)间的通信,对channel进行发送(send)或接收(receive)操作可能会阻塞当前协程。
用make创建一个channel
可以用make(chan Type, BufferSize)
来创建一个新的channel,Type表示channel中元素的类型,BufferSize(可选)为缓冲区大小,缓冲区过大溢出会处理成无缓冲区。
c := make(chan int)
//c := make(chan int, 0) 与上面相等,没有缓冲区
缓冲区
- channel有缓冲区,且缓冲区没有被填满的时候,发送操作不会阻塞goroutine,
- 反之没有缓冲区或缓冲区被填满的channel,发送操作会阻塞goroutine。
单向channel:ReceiverOnly, SenderOnly
在声明方法时,可以将channel定义为单向的ReceiverOnly或SenderOnly,ReceiverOnly只能接受不能发送,相反地,SenderOnly只能发送不能接受。
也可以在用make
创建单向channel,因为单向channel不能转换为双向channel,没有什么实用意义。
//chrcvr 是单向的ReceiverOnly channel
func recieve(chrcvr <-chan int){
e := <- chrcvr // `chrcvr <- 1`报错,不能编译
//...
}
// chsndr 是单向的SenderOnly channel
func send(chsndr chan<- int) {
send <- 3 //`<- send` 报错,不能编译
}
c := make(chan int)
go func(rcvr <-chan int) {
println(<-rcvr)
}(c)
c <- 1
close(channel)
The close built-in function closes a channel, which must be either bidirectional or send-only. It should be executed only by the sender, never the receiver, and has the effect of shutting down the channel after the last sent value is received. After the last value has been received from a closed channel c, any receive from c will succeed without blocking, returning the zero value for the channel element. The form
x, ok := <-c
will also set ok to false for a closed channel.
close(c chan<-Type)
方法关闭一个双向或发送方channel。应该由发送方而不是接收方执行这个方法,并会在最后一个被发送的值被接收后关闭该channel。在关闭的channel的最后一个值被接收后,任何接收都会无阻碍地成功地返回channel元素的零值。对关闭的通道使用x,ok := <-c
格式,也会把ok赋值为false
。
类型
这篇文章提到channel是值拷贝的。
select
select
会从可能的发送(send)或接受(receive)操作集合中选择一个执行,它的语法与switch
相似。
select {
case i := <-c1:
println(i)
case c2 <- 123:
//...
default:
//...
}
- 如果集合中的操作都不能执行,阻塞直到其中一个可以执行;
- 如果集合中有一个或多个操作可以执行,随机执行一个;
nil的channel会阻塞协程,如果select
中只有nil的channel,或者select没有选项select{}
,select也会阻塞协程。default
使select
不会阻塞:
- 如果除了default之外的操作可以执行,执行其中一个;
- 如果其他操作都不能执行,执行default。
有疑问加站长微信联系(非本文作者)