[Go语言系列] 10. Go 语言控制语句

Go语言系列知识快速查看入口

:point_down::point_down::point_down:


本章内容

10.1 if 条件语句

第一种形式:

if 布尔表达式 {
    // do something

第二种形式:

if initialization; condition {
    // do something
}

示例:

package main 

import "fmt"

func main() {
        
    // 第一种形式
	var a int = 10
	if a < 20 {
		fmt.Println("a 小于 20")
	}
	
	// 第二种形式
	if b := 15; b < 20 {
		fmt.Println("b 小于 20")
	}
}

输出:

a 小于 20
b 小于 20

10.2 if…else 条件语句

第一种形式:

if condition {
    // do something
} else {
    // do something
}

第二种形式:

if initialization; condition {
    // do something
} else if {
    // do something
}

示例

package main

import "fmt"

func main() {

	// 第一种形式
	n := 7
	if n >= 0 {
		fmt.Printf("%d is >=0\n", n)
	} else {
		fmt.Printf("%d is < 0\n", n)
	}

	// 第二种形式
	if bool1 := true; !bool1 {
		fmt.Printf("you are not right\n")
	} else if bool1 {
		fmt.Printf("you are right\n")
	}

}

输出

7 is >=0
you are right

10.3 switch 语句

每一个case分支都是唯一的,从上至下逐一测试,直到匹配为止。如果在执行完每个分支的代码后,还希望继续执行后续分支的代码,可以使用fallthrough关键字来达到目的。

switch var1 {
    case val1:
      ...
    case val2:
      ...
    default:
      ...
}

示例:

package main 

import "fmt"

func main() {

	switch n := 7; {
	case n > 0 && n == 7 :
		fmt.Printf("%d is > 0 && n == 7\n", n)
		fallthrough
	case n > 5 || n == 5:
		fmt.Printf("%d is > 5 || n ==5\n", n)
	default:
		fmt.Printf("%d is > unavailable\n", n)
	}
}

输出:

7 is > 0 && n == 7
7 is > 5 || n ==5

10.4 select 条件语句

select 是Go中的一个控制语句,类似于用于通信的switch语句。每个case必须是一个通信操作,要么是发送要么是接收。

select 随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。一个默认的子句(default)应该总是可运行的。

select {
case communication clause :
    statement(s)
case communication clause:
    statement(s)
    /* 你可以定义任意数量的case */
default: /* 可选 */
    statement(s)
}

Notes:

  • 每个case都必须是一个通信
  • 所有channel表达式都会被求值
  • 所有被发送的表达式都会被求值
  • 如果任意某个通信可以进行,它就执行,其他被忽略。
  • 如果有多个case都可以运行,select会随机公平地选出一个执行,其他不会执行。
    否则:
    • a. 如果有default子句,则执行该语句。
    • b. 如果没有default子句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。

示例

package main

import "fmt"

func main() {

	var c1, c2, c3 chan int
	var i1, i2 int
	select {
	case i1 = <-c1: // 接收通道里的数据
		fmt.Println("received ", i1, " from c1")
	case c2 <- i2: // 向通道发送数据
		fmt.Println("sent ", i2, " to c2")
	case i3, ok := (<-c3): // same as: i3, ok := <-c3
		if ok {
			fmt.Println("received ", i3, " from c3")
		} else {
			fmt.Println("c3 is closed")
		}
	default:
		fmt.Println("no communication")	
	}
}

输出

no communication

10.5 for循环

for循环是一个循环控制结构,可以执行指定次数的循环。

第一种形式

for init; condition; post { }

第二种形式

for condition{ }

第三种形式

for { }

说明

  • init:一般为赋值表达式,给控制变量赋初值。
  • condition:关系表达式或逻辑表达式,循环控制条件。
  • post:一般为赋值表达式,给控制变量增量或减量。

for语句执行过程如下:

  • 先对表达式1(init)赋初值。
  • 判别赋值表达式init是否满足给定条件,若其值为真,满足循环条件,则执行循环体内语句,然后执行post,进入第二次循环,再判别condition;否则判断condition的值为假,不满足条件,就终止for循环,执行循环体外语句。

示例

package main

import "fmt"

func main() {
    // 第一种形式
    sum := 0
	for i := 0; i <= 10; i ++ {
        sum += i
    }
	fmt.Println(sum)

    // 第二种形式
    sum2 := 1
	for sum2 <= 10 {
		sum2 += sum2
	}
	fmt.Println(sum2)

	// 第三种形式
	sum3 := 0
	for {
		sum3 ++  // 无限循环下去
	}
	fmt.Println(sum3) // 无法输出,程序也会报错"unreachable code"

	// 要停止无限循环,可以在命令窗口按下 ctrl-c
}

10.6 循环嵌套

示例

package main

import "fmt"

func main() {

	for n := 1; n < 10; n++ {
		for m := 1; m <= n; m++ {
			fmt.Printf("%d * %d = %d\t",m,n,m*n)
		}
		fmt.Println()
	}
}

输出

1 * 1 = 1
1 * 2 = 2       2 * 2 = 4
1 * 3 = 3       2 * 3 = 6       3 * 3 = 9
1 * 4 = 4       2 * 4 = 8       3 * 4 = 12      4 * 4 = 16
1 * 5 = 5       2 * 5 = 10      3 * 5 = 15      4 * 5 = 20      5 * 5 = 25
1 * 6 = 6       2 * 6 = 12      3 * 6 = 18      4 * 6 = 24      5 * 6 = 30      6 * 6 = 36
1 * 7 = 7       2 * 7 = 14      3 * 7 = 21      4 * 7 = 28      5 * 7 = 35      6 * 7 = 42      7 * 7 = 49
1 * 8 = 8       2 * 8 = 16      3 * 8 = 24      4 * 8 = 32      5 * 8 = 40      6 * 8 = 48      7 * 8 = 56      8 * 8 = 64
1 * 9 = 9       2 * 9 = 18      3 * 9 = 27      4 * 9 = 36      5 * 9 = 45      6 * 9 = 54      7 * 9 = 63      8 * 9 = 72      9 * 9 = 81

10.7 break 语句

Go语言中的break语句用于以下三方面:

  • 在单次for循环语句中跳出循环,并开始执行循环之后的语句
  • 在多重循环中,可以用标号label标出想break的循环。
  • break在switch(开关语句)中在执行一条case后跳出语句。

示例1:在单次for循环中使用break

package main

import "fmt"

func main() {
	var a int = 10
	for a < 20 {
		fmt.Println(a)
		a++;
		if a > 15 {
			break;
		}
	}
}

输出

10
11
12
13
14
15

从输出结果看出,程序在变量a大于15的时候跳出了循环。

示例2:在多重循环中使用break

以下分别示例了使用标记和不使用标记的区别:

package main

import "fmt"

func main() {
	
	// 不使用标记
	fmt.Println("----------break----------")
	for i := 1; i <= 3; i++ {
		fmt.Printf("i: %d\n", i)
		for i2 := 11; i2 <= 13; i2++ {
			fmt.Printf("i2: %d\n", i2)
			break
		}
	}

	// 使用标记
	fmt.Println("-------break label-------")
	re:
		for i := 1; i <= 3; i++ {
			fmt.Printf("i: %d\n", i)
			for i2 := 11; i2 <= 13; i2++ {
				fmt.Printf("i2: %d\n", i2)
				break re
			}
		}
}

输出

----------break----------
i: 1
i2: 11
i: 2
i2: 11
i: 3
i2: 11
-------break label-------
i: 1
i2: 11

示例3:在switch语句中使用break

package main

import "fmt"

func main() {
	
	switch a := 10; {
	case a < 20:
		fmt.Println("a<20")
		break;
	case a < 30:
		fmt.Println("a<30")
		break;
	default:
		fmt.Println("error")
	}
}


输出

a<20

参考链接:Go 语言 break 语句 | 菜鸟教程

10.8 continue语句

Go语言的continue语句有点像break语句,但是continue不是跳出循环,而是跳过当前循环执行下一次循环语句。
在多重循环中,可以用标号label标出想continue的循环。

示例1:单次循环中使用continue

package main

import "fmt"

func main() {

	var a int = 10

	for a < 20 {
		a++
		if a == 15 {
			continue;
		}
		fmt.Printf("a 的值为:%d\n", a)
	}
}

输出

a 的值为:11
a 的值为:12
a 的值为:13
a 的值为:14
a 的值为:16
a 的值为:17
a 的值为:18
a 的值为:19
a 的值为:20

示例2:多重循环中使用continue

package main

import "fmt"

func main() {

    // 不使用标记
    fmt.Println("---- continue ---- ")
    for i := 1; i <= 3; i++ {
        fmt.Printf("i: %d\n", i)
            for i2 := 11; i2 <= 13; i2++ {
                fmt.Printf("i2: %d\n", i2)
                continue
            }
    }

    // 使用标记
    fmt.Println("---- continue label ----")
    re:
        for i := 1; i <= 3; i++ {
            fmt.Printf("i: %d\n", i)
                for i2 := 11; i2 <= 13; i2++ {
                    fmt.Printf("i2: %d\n", i2)
                    continue re
                }
        }
}

输出

---- continue ---- 
i: 1
i2: 11
i2: 12
i2: 13
i: 2
i2: 11
i2: 12
i2: 13
i: 3
i2: 11
i2: 12
i2: 13
---- continue label ----
i: 1
i2: 11
i: 2
i2: 11
i: 3
i2: 11

参考链接:Go 语言 continue 语句 | 菜鸟教程

10.9 goto语句

Go 语言的 goto 语句可以无条件地转移到过程中指定的行。

goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。

但是,在结构化程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。

goto label;
..
.
label: statement;

示例

在变量 a 等于 15 的时候跳过本次循环并回到循环的开始语句 LOOP 处:

package main

import "fmt"

func main() {
   /* 定义局部变量 */
   var a int = 10

   /* 循环 */
   LOOP: for a < 20 {
      if a == 15 {
         /* 跳过迭代 */
         a = a + 1
         goto LOOP
      }
      fmt.Printf("a的值为 : %d\n", a)
      a++    
   }  
}

输出

a的值为 : 10
a的值为 : 11
a的值为 : 12
a的值为 : 13
a的值为 : 14
a的值为 : 16
a的值为 : 17
a的值为 : 18
a的值为 : 19

参考链接:Go 语言 goto 语句 | 菜鸟教程