Go_Channel详解
*每天都有新体验
Channel类型:
Channel的类型有三种,<-指明方向,如果没有指明方向,那就是双向的。
|
|
<-总是优先和最左面的类型结合。
|
|
创建Channel
make (chan int ,100) 100是容量(capacity).如果容量为零,就是没有缓存。只有sender和receiver都准备好了之后他们的通讯才会开始。如果设置了缓存,只有buffer慢了之后send才会阻塞,而只有缓存空了之后,receive才会阻塞。一个nil channel不会通信。
- 可以在多个goroutine中同时往一个channel中receive/send数据,不必考虑额外的同步措施。
- channel是一个先进先出队列。
- recevie支持multi-valued assignment
v,ok:=<-ch可以检查channel是否关闭。
send/receive
send:
c:=make(chan int) c<-3send向channel中发送数据。
-
在通讯开始前,expression必需先求出值来。
-
1 2 3 4 5 6 7c := make(chan int) defer close(c) go func() { c <- 3 + 4 }() i := <-c fmt.Println(i) ////out 7
-
-
send被执行前通讯一直被阻塞,无缓存的channel只有在receive准备好后才会被执行。
-
向一个已经被关闭的channel中发送数据会导致
run-time panic -
向
nil channel中发送数据会一直被阻塞
receive:
<-ch用来从channel中接受数据,这个表达式会一直阻塞,直到有数据可以接收。
- 从一个
nil channel中接收数据会一直被阻塞 - 从一个关闭的channel中接受数据不会被阻塞,而是立即返回对应元素的零值。
Range处理
示例
|
|
- range c产生的迭代值为channel中发送的值,替代了
<-ch - 这个
for range会一直迭代直到channel被关闭。
select
示例:
|
|
- select选择一组可能的send或者receice操作处理。
- 如果同时多个channel不被阻塞,则会随机选择一个case处理
- 没有能处理case则选择defaulf处理,如果没有设置
dafault case则一直被阻塞
timeout
利用select可以很容易的设置超时。
|
|
Timer和Ticker
timer:=time.NewTimer(time.second*2)
|
|
- newtime相当于延时
- ticker相当于一个缓存channel,以等间隔时间发送数据