分享
  1. 首页
  2. 文章

Channels in Go range and select

谢权 · · 2008 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

这是Channels in go的第二篇,这篇主要讲range and select ,第一篇可以打开这个链接https://xiequan.info/channels-in-go/

接收Channle的数据的时候我们会遇到,什么时候需要停止等待数据。有更多数据,还是已经全部完成?我们是继续等待还是继续?一种方法就是不断的轮询和检查通道是否已经关闭,但是这种方法并不是特别有效。

Channels and range

Go提供了range关键词,当它与Channel 一起使用的时候他会等待channel的关闭。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
packagemain
import(
"fmt"
"time"
"strconv"
)
func makeCakeAndSend(cs chan string,count int){
fori:=1;i<=count;i++{
cakeName:="Strawberry Cake "+strconv.Itoa(i)
cs<-cakeName//send a strawberry cake
}
}
func receiveCakeAndPack(cs chan string){
fors:=rangecs{
fmt.Println("Packing received cake: ",s)
}
}
func main(){
cs:=make(chan string)
go makeCakeAndSend(cs,5)
go receiveCakeAndPack(cs)
//sleep for a while so that the program doesn’t exit immediately
time.Sleep(3*1e9)
}
Shell
1
2
3
4
5
Packing received cake:Strawberry Cake1
Packing received cake:Strawberry Cake2
Packing received cake:Strawberry Cake3
Packing received cake:Strawberry Cake4
Packing received cake:Strawberry Cake5

Channels and select

golang 的 select 的功能和 select, poll, epoll 相似, 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作。注意到 select 的代码形式和 switch 非常相似, 不过 select 的 case 里的操作语句只能是 IO 操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
packagemain
import(
"fmt"
"time"
"strconv"
)
func makeCakeAndSend(cs chan string,flavor string,count int){
fori:=1;i<=count;i++{
cakeName:=flavor+" Cake "+strconv.Itoa(i)
cs<-cakeName//send a strawberry cake
}
close(cs)
}
func receiveCakeAndPack(strbry_cs chan string,choco_cs chan string){
strbry_closed,choco_closed:=false,false
for{
//if both channels are closed then we can stop
if(strbry_closed&&choco_closed){return}
fmt.Println("Waiting for a new cake ...")
select{
casecakeName,strbry_ok:=<-strbry_cs:
if(!strbry_ok){
strbry_closed=true
fmt.Println(" ... Strawberry channel closed!")
}else{
fmt.Println("Received from Strawberry channel. Now packing",cakeName)
}
casecakeName,choco_ok:=<-choco_cs:
if(!choco_ok){
choco_closed=true
fmt.Println(" ... Chocolate channel closed!")
}else{
fmt.Println("Received from Chocolate channel. Now packing",cakeName)
}
}
}
}
func main(){
strbry_cs:=make(chan string)
choco_cs:=make(chan string)
//two cake makers
go makeCakeAndSend(choco_cs,"Chocolate",3)//make 3 chocolate cakes and send
go makeCakeAndSend(strbry_cs,"Strawberry",3)//make 3 strawberry cakes and send
//one cake receiver and packer
go receiveCakeAndPack(strbry_cs,choco_cs)//pack all cakes received on these cake channels
//sleep for a while so that the program doesn’t exit immediately
time.Sleep(2*1e9)
}
Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Waiting foranewcake...
Received from Strawberry channel.Now packing Strawberry Cake1
Waiting foranewcake...
Received from Chocolate channel.Now packing Chocolate Cake1
Waiting foranewcake...
Received from Chocolate channel.Now packing Chocolate Cake2
Waiting foranewcake...
Received from Strawberry channel.Now packing Strawberry Cake2
Waiting foranewcake...
Received from Strawberry channel.Now packing Strawberry Cake3
Waiting foranewcake...
Received from Chocolate channel.Now packing Chocolate Cake3
Waiting foranewcake...
...Strawberry channel closed!
Waiting foranewcake...
...Chocolate channel closed!

select 会一直等待等到某个 case 语句完成, 也就是等到成功从 ch1 或者 ch2 中读到数据。 则 select 语句结束

Channels in Go range and select

有疑问加站长微信联系(非本文作者)

本文来自:谢权SELF

感谢作者:谢权

查看原文:Channels in Go range and select

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2008 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏