Go 控制与并发
2020-07-10 22:09:21 0 举报
AI智能生成
Golang the good parts
作者其他创作
大纲/内容
流程控制
if
单if
if condition {<br> //do something<br>}
if SimpleStmt ; condition {<br> //do something<br>}
惯用法
if err := file.Chmod(0664); err != nil {<br> log.Print(err)<br> return err<br>}
if-else
if condition {<br> //do something1<br>} else {<br> //do something2<br>}
推荐单if形式:
if condition {<br> //do something1<br>} <br> //do something2<br>
串联if-else
if condition1 {<br> //do something<br>} else if condition2 {<br> //do something<br>} else {<br> //do something<br>}
else-if的数量是没有限制的,但是为了代码的可读性,尽量少用else-if
for
基本形式
for 初始化语句; 条件语句; 修饰语句 {<br>}
for i := 0; i < 3; i++ {<br> fmt.Println("for inde x = ", i)<br>}
条件形式
i := 5<br>for i >= 0 {<br> i--;<br> fmt.Println(i)<br>}
go没有while,可用条件形式模拟
死循环
for {<br> //do something<br>}<br>
for-break
结束整个循环体
for-continue
结束循环体的本次执行
continue只能用于for循环中
for-range
迭代器形式
配合string array slice map channel等数据结构一起使用
《Go编程语言规范》中的描述
四种形式
for i, v := range a { <br> ...<br>} <br>
for i := range a { // ignores value<br> ...<br>} <br>
for _, v := range a { // ignores index <br> ...<br>} <br>
for range a { // ignores index and value<br> ...<br>} <br>
switch
形式化定义
ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .<br>ExprCaseClause = ExprSwitchCase ":" StatementList .<br>ExprSwitchCase = "case" ExpressionList | "default" .
switch+语句+表达式
switch stmt;expr {... }
switch+表达式
switch expr {... }
单switch
switch {... }
能够模拟if-else,见例3
对应例子
case
可以在一个 case 中包含多个表达式,每个表达式用逗号分隔
default
可以放在 switch 语句的任何位置,但通常放在最后
fallthrough
用于标明执行完当前 case 语句之后,按顺序执行下一个case 语句
fallthrough 必须是 case 语句块中的最后一条语句。如果它出现在语句块的中间,编译器将会报错
不允许出现于type-switch
type-switch
跳转
goto + label
break(+ label)
可用于for switch select
continue(+ label)
只能用于for
例子
并发
channel
类型定义
ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
三种类型
双向 chan T // 可以接收和发送类型为 T 的数据<br>只写 chan<- float64 // 只可以用来发送 float64 类型的数据<br>只读<-chan int // 只可以用来接收 int 类型的数据
make
无缓冲
make(chan int)
有缓冲
make(chan int, 100)
容量(capacity)代表Channel容纳的最多的元素的数量,代表Channel的缓存的大小。<br>如果没有设置容量,或者容量设置为0, 说明Channel没有缓存,只有sender和receiver都准备好了后它们的通讯(communication)才会发生(Blocking)。<br>如果设置了缓存,就有可能不发生阻塞, 只有buffer满了后 send才会阻塞, 而只有缓存空了后receive才会阻塞。一个nil channel不会通信。<br>
close
ch 已关闭,ch<- 立即导致panic,不管ch是否满
ch 已关闭,<-ch 可以不断读取数据,读完继续读取则返回零值
ch 已关闭,for-range 可以不断读取数据,读完退出循环
c := make(chan int, 10)<br>c <- 1<br>c <- 2<br>close(c)<br>for i := range c {<br> fmt.Println(i)<br>}
i, ok := <-c<br>
可以查看Channel的状态,判断值是零值还是正常读取的值
send
定义
SendStmt = Channel "<-" Expression .<br>Channel = Expression .
ch<-10
规则
无缓存的channel只有在receiver准备好后send才被执行。如果有缓存,并且缓存未满,则send会被执行
往一个已经被close的channel中继续发送数据会导致run-time panic
往nil channel中发送数据会一致被阻塞着
recv
<-ch 用来从channel ch中接收数据,这个表达式会一直被block,直到有数据可以接收。 <br>
for-range
例子
c := make(chan int)<br>for i := range c {<br> fmt.Println(i)<br> }<br>
遍历channel直到为空,此时<br>如果channel被关闭则退出循环;<br>如果channel不关闭则一直阻塞<br>
参考资料
Go Channel 详解
由浅入深剖析 go channel
select
select就是用来监听和channel有关的收发操作,当数据可接收或可发送时触发相应的动作
select执行步骤
表达式求值
对所有出现在case语句中的通道表达式(elem <-ch 或 ch <- elem)求值, 得到所有的<接收通道>以及<发送通道+待发送值>
求值顺序:按代码书写顺序,即自上而下、从左到右
分支触发
就绪(随机选取)->default->阻塞
如果有一个或多个IO操作可以完成,则Go运行时系统会随机的选择一个执行,<br>否则的话,如果有default分支,则执行default分支语句,<br>如果连default都没有,则select语句会一直阻塞,直到至少有一个IO操作可以进行<br>
分支执行
case
每个case操作一个channel,要么读,要么写
default
如果所有case都未就绪,则执行default
break
break之后的语句不在执行,直接跳出select
例子
《Go编程语言规范》中的例子
参考资料
定时器
ticker
ticker := time.NewTicker(1 * time.Second)<br>for range ticker.C {<br> ... <br>}
timer
timer := time.NewTimer(1 * time.Second)<br> select {<br> case <-timer.C:<br> fmt.Println("timeout")<br> }
after
select {<br>case <-time.After(3*time.Second ):<br> fmt.Println("timeout")<br>} <br>
waitgroup
context
子主题
数据结构
主要函数
Background() Context
用于main函数、初始化、tests、或网络请求的根ctx
TODO() Context
无明确意图时使用todo ctx
WithCancel(parent Context) (ctx Context, cancel CancelFunc)
主动调用触发取消
WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
时间触发取消,绝对时间
WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
时间触发取消,相对时间
WithValue(parent Context, key, val interface{}) Context
kv型ctx,用于传递数据<br>
参考资料
深入理解Golang之Context
Golang 之context库用法
Go Concurrency Patterns: Context
反射
包
模块
0 条评论
下一页