Golang学习笔记-04流程控制

前言:

go语言的流程控制语句总共只有以下几种:

  1. if else (条件判断)
  2. for、for range (键值循环)
  3. switch case (选择)
  4. goto (跳转到指定标签)
  5. break (跳出循环)
  6. continue (结束当前循环,继续下次循环)

注意:go语言中是没有 while 和 do…while 语句的,但是使用 for 或 for+if 是可以模拟出这两个循环语句的

条件分支语句

if else条件判断语句

单if

1
2
3
if 布尔表达式 {
/* 在布尔表达式为 true 时执行 */
}

if else

1
2
3
4
5
if 布尔表达式 {
/* 在布尔表达式为 true 时执行 */
} else {
/* 在布尔表达式为 false 时执行 */
}

if - else if - else

1
2
3
4
5
6
7
if 布尔表达式1 {
/* 在布尔表达式1为 true 时执行 */
} else if 布尔表达式2{
/* 在布尔表达式1为 false ,布尔表达式2为true时执行 */
} else{
/* 在上面两个布尔表达式都为false时,执行*/
}

Go语言规定与if匹配的左括号{必须与if和表达式放在同一行,{放在其他位置会触发编译错误。 同理,与else匹配的{也必须与else写在同一行,else也必须与上一个ifelse if右边的大括号在同一行。func、struct 的 { 也是。

if 条件判断特殊写法

if条件判断还有一种特殊的写法,可以在 if 表达式之前添加一个执行语句,再根据变量值进行判断

1
2
3
4
5
6
if statement; condition {  
}

if condition{

}

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
"fmt"
)

func main() {
if num := 10; num % 2 == 0 { //checks if number is even
fmt.Println(num,"is even")
} else {
fmt.Println(num,"is odd")
}
}

注意,num的定义在if里,那么只能够在该if..else语句块中使用。

switch语句

switch是一个条件语句,它计算表达式并将其与可能匹配的列表进行比较,并根据匹配执行代码块。它可以被认为是一种惯用的方式来写多个if else子句,使用switch语句可方便地对大量的值进行条件判断。

语法

1
2
3
4
5
6
7
8
switch var1 {
case val1:
...
case val2:
...
default:
...
}

变量 var1 可以是任何类型,而 val1 和 val2 则可以是同类型的任意值。类型不被局限于常量或整数,但必须是相同的类型;或者最终结果为相同类型的表达式。

switch 语句每一个 case 分支都是唯一的,从上直下逐一测试,直到匹配为止,如果都不匹配则会执行default语句块。

Go语言规定每个switch只能有一个default分支,case后的常量值不能重复。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func switchDemo1(finger int) {
switch finger {
case 1:
fmt.Println("大拇指")
case 2:
fmt.Println("食指")
case 3:
fmt.Println("中指")
case 4:
fmt.Println("无名指")
case 5:
fmt.Println("小拇指")
default:
fmt.Println("无效的输入!")
}
}

和其他语言(C++/Java)不同的,Go里面switch默认相当于每个case最后带有break,匹配成功后不会自动向下执行其他case,而是跳出整个switch, 但是可以使用 fallthrough 强制执行后面的case代码。

注意:fallthrough应该是某个case的最后一行。如果它出现在中间的某个地方,编译器就会抛出错误。

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func switchDemo5() {
s := "a"
switch {
case s == "a":
fmt.Println("a")
fallthrough
case s == "b":
fmt.Println("b")
case s == "c":
fmt.Println("c")
default:
fmt.Println("...")
}
}

输出

1
2
a
b

分支还可以使用表达式,这时候switch语句后面不需要再跟判断变量。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
func switchDemo4() {
age := 30
switch {
case age < 25:
fmt.Println("好好学习吧")
case age > 25 && age < 35:
fmt.Println("好好工作吧")
case age > 60:
fmt.Println("好好享受吧")
default:
fmt.Println("活着真好")
}
}

同时,一个分支可以有多个值,多个case值中间使用英文逗号分隔。如:

1
2
3
4
5
6
7
8
9
10
func testSwitch3() {
switch n := 7; n {
case 1, 3, 5, 7, 9:
fmt.Println("奇数")
case 2, 4, 6, 8:
fmt.Println("偶数")
default:
fmt.Println(n)
}
}

Type Switch

switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型。

1
2
3
4
5
6
7
8
9
switch x.(type){
case type:
statement(s);
case type:
statement(s);
/* 你可以定义任意个数的case */
default: /* 可选 */
statement(s);
}

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

func main() {
var x interface{}

switch i := x.(type) {
case nil:
fmt.Printf(" x 的类型 :%T",i)
case int:
fmt.Printf("x 是 int 型")
case float64:
fmt.Printf("x 是 float64 型")
case func(int) float64:
fmt.Printf("x 是 func(int) 型")
case bool, string:
fmt.Printf("x 是 bool 或 string 型" )
default:
fmt.Printf("未知型")
}
}

运行结果:

1
x 的类型 :<nil>

循环语句

Go 语言中的所有循环类型均可以使用for关键字来完成。

基本语法的for

for循环的基本格式如下,和C++,Java中的for语句类似(但是少了括号):

1
2
3
for 初始语句;条件表达式;结束语句{
循环体语句
}

省略语句的for

所有的三个组成部分,即初始化、条件和post都是可选的。

for循环的初始语句可以被忽略,但是初始语句后的分号必须要写,例如:

1
2
3
4
5
6
func forDemo() {
i := 0
for ; i < 10; i++ {
fmt.Println(i)
}
}

for循环的初始语句和结束语句都可以省略,效果与其他语言中的while相似,注意go中是没有while的

1
2
3
4
5
6
7
func forDemo() {
i := 0
for i < 10 {
fmt.Println(i)
i++
}
}

无限循环

1
2
3
for {
循环体语句
}

for循环可以通过breakgotoreturnpanic语句强制退出循环。

for range(键值循环)

go语言中可以使用for range遍历数组array、切片slice、字符串string、map 及通道(channel)。 通过for range遍历的返回值有以下规律:

  1. 数组、切片、字符串返回索引和值。

    1
    for i,v:= range array
  2. map返回键和值。

    1
    for k,v:= range map
  3. 通道(channel)只返回通道内的值。

    1
    for v := range channel

    注意:在需要时,可以使用匿名变量对 for range 的变量进行选取。

其他语句

goto

goto语句通过标签进行代码间的无条件跳转。goto语句可以在快速跳出循环、避免重复退出上有一定的帮助。类似汇编语言中的goto

break

break语句可以结束forswitchselect的代码块。

break语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的forswitchselect的代码块上。 如:

1
2
3
4
5
6
7
8
9
10
11
12
func breakDemo1() {
BREAKDEMO1:
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
break BREAKDEMO1
}
fmt.Printf("%v-%v\n", i, j)
}
}
fmt.Println("...")
}

continue

continue语句可以结束当前循环,开始下一次的循环迭代过程,仅限在for循环内使用,作用和其他语言continue类似。

但是如果是嵌套循环时,在 continue语句后添加标签时,表示开始标签对应的循环。如

1
2
3
4
5
6
7
8
9
10
11
12
func continueDemo() {
forloop1:
for i := 0; i < 5; i++ {
// forloop2:
for j := 0; j < 5; j++ {
if i == 2 && j == 2 {
continue forloop1
}
fmt.Printf("%v-%v\n", i, j)
}
}
}
文章作者: Oxywen
文章链接: https://oxywen.cn/post/go/5/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 不闻星河须臾