Go流程控制

A for循环
for init;condition;end{
circle body
}
其中, init 为初始化语句,仅在第一次循环前执行;condition 为条件表达式,在每次循环中判断是否满足执行条件;end 为结束语句,在每次循环结束时执行。
上述三者都可以缺省,此时 for 将变成一个无限循环语句。即for {}
如果缺省初始化语句和结束语句,for 将变得类似 while 语句,而 Go 中不存在 while 关键字。
在 for 循环中可以使用 break 关键字跳出当前循环,或者使用 continue 关键字跳到下一个循环。
B 分支控制
Go 中提供两种分支控制语句,分别为 if-else 语句和 switch 语句。if-else 语句用于进行条件分支控制,简单的表达式如下:
复制
if condition1 {
branch1
} else if condition2 {
branch2
} else {
branch3
}
switch 是比 if-else 更为简便的用于编写大量条件分支的方法。
Go 中的 switch 与其他编程语言类似,但存在不同之处:
Go 中的 switch 只执行匹配 case 后面的代码块,无须使用 break 关键字跳出 switch 选择体。
除非明确使用 fallthrough 关键字对上下两个 case 进行连接,否则 switch 执行完匹配 case 后面的代码块后将退出 switch。
一个简单的 switch 例子如下:
package main
import (
"fmt"
"time"
)
func main() {
nowTime := time.Now()
switch nowTime.Weekday(){
case time.Saturday:
fmt.Println("take a rest")
case time.Sunday:
fmt.Println("take a rest")
case time.Wednesday:
fmt.Println("today is wednesday")
fallthrough
default:
fmt.Println("you need to work")
}
上面结果//today is wednesday you need to work
switch {
case nowTime.Weekday() >= time.Monday && nowTime.Weekday() <= time.Friday:
fmt.Println("you need to work")
default:
fmt.Println("take a rest")
}
}
当 switch 后没有携带需要判断的条件时,就可以在 case 后面使用判断表达式,如上述代码所示,这种写法就与 if-else 语句十分类似,但显得更为清晰
C select 多路复用
一个select语句用来选择哪个case中的发送或接收操作可以被立即执行。它类似于switch语句,但是它的case涉及到channel有关的I/O(收发)操作
当需要从多个 channel 中接收消息时,可以使用 Go 提供的 select 关键字,它提供类似多路复用的能力,使得 goroutine 可以同时等待多个 channel 的读写操作。一个简单的例子如下:
package main
import (
"fmt"
"time"
)
func send(ch chan int, begin int ) {
// 循环向 channel 发送消息
for i :=begin ; i< begin + 10 ;i++{
ch <- i
}
}
func receive(ch <-chan int) {
val := <- ch
fmt.Println("receive:", val)
}
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go send(ch1, 0)
go receive(ch2)
// 主 goroutine 休眠 1s,保证调度成功
time.Sleep(time.Second)
for {
select {
case val := <- ch1: // 从 ch1 读取数据
fmt.Printf("get value %d from ch1\n", val)
case ch2 <- 2 : // 使用 ch2 发送消息
fmt.Println("send value by ch2")
case <-time.After(2 * time.Second): // 超时设置
fmt.Println("Time out")
return
}
}
}
说明
case <-chan1:
// 如果chan1成功读到数据,则进行该case处理语句
case chan2<-1
// 如果成功向chan2写入数据,则进行该case处理语句
time.After() ,在等待给定的一段时间后,向返回值发送当前时间,返回值是有一个单向只读通道
ch <-chan int 这里代表只读的channel ch
由于 ch2 中的消息仅被接收一次,所以仅出现一次“send value by ch2”,后续消息的发送将被阻塞。
select 语句分别从 3 个 case 中选取返回的 case 进行处理,当有多个 case 语句同时返回时,select 将会随机选择一个 case 进行处理。
如果 select 语句的最后包含 default 语句,该 select 语句将会变为非阻塞型,即当其他所有的 case 语句都被阻塞无法返回时,select 语句将直接执行 default 语句返回结果。 我们在最后的 case 语句使用了 <-time.After(2 * time.Second) 的方式指定了定时返回的 channel,这是一种有效从阻塞的 channel 中超时返回的小技巧。
D goto 语句
Go 语言的 goto 语句可以无条件地转移到过程中指定的行。goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
但是,在结构化程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难
栗子:
goto label; .. . label: statement;

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注