Go里的流程控制方法主要有以下几种方式:
if - else条件语句
switch - case 选择语句
for - range 循环语句
goto 无条件跳转语句
defer 延迟执行
Go里的条件语句模型是
if 条件1 {
分支1
} else if 条件2 {
分支2
} else {
分支
}
Go编译器,对于{
和}
的位置有严格的要求,它要求else if
或 else
和两边的花括号,必须在同一行。
由于Go是强类型
, 所以要求你条件表达式必须严格返回布尔型的数据(nil
和0
和1
都不行)。
import "fmt"
func main() {
age := 20
if age > 18 {
fmt.Println("已经成年了")
}
}
如果条件里需要满足多个条件,可以使用&&
和||
&&:表示且,左右都需要为true,最终结果才是true,否则为false
||:表示或,左右只需要有一个为true, 最终结果即为true,否则为false
import "fmt"
func main() {
age := 20
gender := "male"
if (age > 18 && gender == "male") {
fmt.Println("是成年男性")
}
}
if - else
import "fmt"
func main() {
age := 20
if age > 18 {
fmt.Println("已经成年了")
} else {
fmt.Println("还未成年")
}
}
if - else if - else
import "fmt"
func main() {
age := 20
if age > 18 {
fmt.Println("已经成年了")
} else if age >12 {
fmt.Println("已经是青少年了")
} else {
fmt.Println("还不是青少年")
}
}
在if里可以允许先运行一个表达式,取得变量后,再对其进行判断,比如第一个例子里代码也可以写成这样
import "fmt"
func main() {
if age := 20; age> 18 {
fmt.Println("已经成年了")
}
}
Go里的选择语句模型是
switch 表达式 {
case 表达式1:
代码块
case 表达式2:
代码块
case 表达式3:
代码块
case 表达式4:
代码块
default:
代码块
}
拿switch后的表达式分别和case后的表达式进行对比,只要有一个case满足条件,就会执行对应的代码块,然后直接退出switch-case,如果一个都没有满足,才会执行default的代码块。
import "fmt"
func main() {
education := "本科"
switch education {
case "博士":
fmt.Println("我是博士")
case "研究生":
fmt.Println("我是研究生")
case "本科":
fmt.Println("我是本科生")
case "大专":
fmt.Println("我是大专生")
case "高中":
fmt.Println("我是高中生")
default:
fmt.Println("学历未达标..")
}
}
case后可以接多个条件,多个条件之间是或
的关系,用逗号隔开。
import "fmt"
func main() {
month := 2
switch month {
case 3, 4, 5:
fmt.Println("春天")
case 6, 7, 8:
fmt.Println("夏天")
case 9, 10, 11:
fmt.Println("秋天")
case 12, 1, 2:
fmt.Println("冬天")
default:
fmt.Println("输入有误...")
}
}
当case后接的是常量
时,该常量只能出现一次。
一下两种情况,在编译时,都会报错:duplicate case "male" in switch
错误案例一
gender := "male"
switch gender {
case "male":
fmt.Println("男性")
// 与上面重复
case "male":
fmt.Println("男性")
case "female":
fmt.Println("女性")
}
错误案例二
gender := "male"
switch gender {
case "male", "male":
fmt.Println("男性")
case "female":
fmt.Println("女性")
}
switch后面可以接一个函数,只要保证case后的值类型与函数的返回值一致即可。
import "fmt"
// 判断一个同学是否有挂科记录的函数
// 返回值是布尔类型
func getResult(args ...int) bool {
for _, i := range args {
if i < 60 {
return false
}
}
return true
}
func main() {
chinese := 80
english := 50
math := 100
switch getResult(chinese, english, math) {
// case 后也必须 是布尔类型
case true:
fmt.Println("该同学所有成绩都合格")
case false:
fmt.Println("该同学有挂科记录")
}
}
switch后可以不接任何变量、表达式、函数。
当不接任何东西时,switch-case就相当于if-else if-else
score := 30
switch {
case score >= 95 && score <= 100:
fmt.Println("优秀")
case score >= 80:
fmt.Println("良好")
case score >= 60:
fmt.Println("合格")
case score >= 0:
fmt.Println("不合格")
default:
fmt.Println("输入有误...")
}
正常情况下switch-case的执行顺序是:只要有一个case满足条件,就会直接退出switch-case,如果一个都没有满足,才会执行default的代码块。
但是有一种情况是例外。
那就是当case使用关键字fallthrough
开启穿透能力的时候。
s := "hello"
switch {
case s == "hello":
fmt.Println("hello")
fallthrough
case s != "world":
fmt.Println("world")
}
代码输出结果:
hello
world
需要注意的是,fallthrough
只能穿透一层,意思是它让你直接执行下个case的语句,而且不需要判断条件。
s := "hello"
switch {
case s == "hello":
fmt.Println("hello")
fallthrough
case s == "xxxx":
fmt.Println("xxxx")
case s != "world":
fmt.Println("world")
}
输出如下,并不会输出最后一个case的结果(即使它符合条件)
hello
xxxx
for 循环的基本模型:
for [condition | (init; condition; increment) | Range]
{
statement(s);
}
for后面可以接三种类型的表达式:
接一个条件表达式 (类似Python的where)
接三个表达式
接一个range表达式
但还有第四种-->不接受表达式
a := 1
for a <= 5 {
fmt.Println(a)
a++
}
for 后面,紧接着三个表达式,使用;
分割。
这三个表达式,各有各的用途
第一个表达式: 初始化控制变量,在整个循环生命周期内,只运行一次;
第二个表达式: 设置循环控制条件,当返回true,继续循环,返回false,结束循环;
第三个表达式: 每次循环开始(除第一次)时,给控制变量递增或递减。
import "fmt"
func main() {
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
}
在Go中,没有while循环,如果要实现无限循环,也可以完全使用for来实现。
当你不加任何的判断条件时,就相当于你每次的判断都为true,程序就会一直处于运行状态,但是一般我们并不会让程序处于死循环,在满足一定的条件下,可以使用关键字break
退出循环体,也可以使用continue
直接跳到下一个循环。
for {
代码块
}
// 等价于
for ;; {
代码块
}
举个栗子:
import "fmt"
func main() {
var i int = 1
for {
if i > 5 {
break
}
fmt.Printf("hello, %d\n", i)
i++
}
}
遍历一个可迭代对象,是一个很常用的操作。在Go可以使用for-range
的方式来实现。
range后可接数组、切片,字符串等
由于range会返回两个值:索引和数据,若你后面的代码用不到索引,需要使用_
接收。
import "fmt"
func main() {
myarr := [...]string{"world", "python", "go"}
for _, item := range myarr {
fmt.Printf("hello, %s\n", item)
}
}
如果你用一个变量来接收的话,接收到的是索引
import "fmt"
func main() {
myarr := [...]string{"world", "python", "go"}
for i := range myarr {
fmt.Printf("hello, %v\n", i)
}
}
goto顾名思义,是跳转的意思。
goto后接一个标签,这个标签的意义是告诉Go程序下一步要执行哪里的代码。
所以这个标签如何放置,放置在哪里,是goto里最需要注意的。
goto 标签;
...
...
标签: 表达式;
goto 可以打破原有代码执行顺序,直接跳转到某一行执行代码。
import "fmt"
func main() {
goto flag
fmt.Println("B")
flag:
fmt.Println("A")
}
执行结果
A
并不会输出B,而只会输出A
goto语句通常与条件语句配合使用。可用来实现条件转移,构成循环,跳出循环体等功能。
举个栗子:
// 实现一个打印1到5的循环
import "fmt"
func main() {
i := 1
flag:
if i <= 5 {
fmt.Println(i)
i++
goto flag
}
}
使用goto实现continue的效果
// 打印1到10的所有偶数
import "fmt"
func main() {
i := 1
flag:
for i <= 10 {
if i%2 == 1 {
i++
goto flag
}
fmt.Println(i)
i++
}
}
goto语句与标签之间不能有变量声明,否则编译错误。
import "fmt"
func main() {
fmt.Println("start")
goto flag
var say = "hello oldboy"
fmt.Println(say)
flag:
fmt.Println("end")
}
编译错误
.\main.go:7:7: goto flag jumps over declaration of say at .\main.go:8:6
基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建