Go 控制语句

if 控制

  • 条件表达式没有括号
  • 支持一个初始化表达式(可以是并行方式)
  • 左大括号必须和条件语句或else在同一行
  • 支持单行模式
  • 初始化语句中的变量为block级别,同时隐藏外部同名变量
1
2
3
4
5
6
7
8
a := true
if a, b, c := 1, 2, 3; a+b+c > 6 {
fmt.Println(">6")
} else {
fmt.Println("<=6")
fmt.Println(a)
}
fmt.Println(a)

for 循环

在 Go 中只有 for 一个循环语句关键字,没有 while ,但是支持3种形式

  • 初始化和步进表达式可以是多个值

  • 条件语句每次循环都会被重新检查,因此不建议在条件语句中使用函数,尽量提前计算好并以变量或常量代替

  • 左大括号必须和条件语句在同一行

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
// 第一种

a := 0
for {
a++
if a > 3 {
break
}
}
fmt.Println(a)

// 结果为4

// 第二种
a := 0
for a <= 3{
a ++
}
fmt.Println(a)
// 结果为4


// 第三种
a := 1
for i:= 0 ; i < 3 ; i++{
a ++
}
println(a)
// 结果为4

死循环

1
2
3
for {
// do something
}

switch 选择

  • 可以使用任何类型或表达式作为条件语句

  • 不需要写break,一旦条件成立自动终止

  • 如希望继续执行下一个case,需要使用 fallthrough 语句

  • 支持一个初始化表达式(可以是并行方式),右侧需要跟分号

  • 左大括号必须和条件语句在同一行

例子1,不需要写break,条件成立会自动终止

1
2
3
4
5
6
7
8
9
10
func sF1(){
a := 1
switch a {
case 0 :
fmt.Println("a=0")
case 1:
fmt.Println("a=1")
}
fmt.Println(a)
}

输出为:

1
2
a=1
1

例子2,如果希望继续执行下一个case,使用 fallthrough

1
2
3
4
5
6
7
8
9
10
11
func sF2() {
a := 1
switch {
case a >= 0:
fmt.Println("a=0")
fallthrough
case a >= 1:
fmt.Println("a=1")
}
fmt.Println(a)
}

输出为:

1
2
3
a=0
a=1
1

例子3,支持一个初始化表达式,需要分号结尾 :

1
2
3
4
5
6
7
8
9
10
11
12
func sF3() {
a := 1
switch b := 1; {
case a+b > 2:
fmt.Println("a+b>2")
case a+b == 2:
fmt.Println("a+b=2")
default:
fmt.Println("a+b<2")
}
fmt.Println(a)
}

输出为:

1
2
a+b<=2
1

在 switch 中 b 的作用域在 switch中有效,所以外面是输出不到它的信息

跳转语句 与 标签

  • 3个语句都可以配合标签使用
  • 标签名区分大小写,若不适用会造成编译错误
  • break 与 continue 配合标签可用于多层循环的跳出
  • goto 是调整执行位置,与其他2个语句配合标签的结果并不相同

break

1
2
3
4
5
6
7
8
9
func breakF() {
for i := 0; i < 3; i++ {
if i > 1 {
fmt.Println(i)
break
}
}
fmt.Println("over")
}

输出:

1
2
2
over

当 i > 1 时,输出当前的值 break 结束循环,并继续执行剩下的代码

拥有2层for时,跳到最外面,使用标签,会跳到与标签同一级,然后执行for后面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func breakF1() {
LABEL:
for {
for i := 0; i < 10; i++ {
if i > 2 {
fmt.Println("break to label,i: ", i)
break LABEL
} else {
fmt.Println(i)
}
}
}
fmt.Println("over")
}

输出:

1
2
3
4
5
0
1
2
break to label,i: 3
over

goto

如果将 break 改为 goto ,将会导致重新进入一次循环,导致死循环

1
2
3
4
5
if i > 2 {
fmt.Println("break to label,i: ", i)
- break LABEL
+ goto LBAEL
}

可以将标签放在 for 之后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- LABEL:
for {
for i := 0; i < 10; i++ {
if i > 2 {
fmt.Println("break to label,i: ", i)
- break LABEL
+ goto LBAEL
} else {
fmt.Println(i)
}
}
}
+ LABEL:
fmt.Println("over")

输出:

1
2
3
4
5
0
1
2
break to label,i: 3
over

continue

例子:

1
2
3
4
5
6
7
8
9
10
11
12
func continueF1() {
LABEL:
for i := 0; i < 3; i++ {
fmt.Println("before i", i)
for {
continue LABEL
fmt.Println(i)
}
fmt.Println("after i", i)
}
fmt.Println("over")
}

结果:

1
2
3
4
before i 0
before i 1
before i 2
over

在 continue 之后都不会执行

1
2
3
4
5
6
7
8
9
func continueF2() {
LABEL:
for i := 0; i < 10; i++ {
for {
fmt.Print(i)
continue LABEL
}
}
}

输出:

1
0123456789

接下将换成 goto 发现输出都是0,其变成了死循环。goto 是调整执行位置

1
000000000000000000000000000000000000000000000000000000000000000000000..............

将 label 放在 goto 的后面

1
2
3
4
5
6
7
8
9
10
func continueF2() {
for i := 0; i < 10; i++ {
for {
fmt.Print(i)
continue LABEL
}
}
LABEL:
// xxxxx
}
- the End -
0%