Golang basic_leaming3 流程控制

Posted 知其黑、受其白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang basic_leaming3 流程控制相关的知识,希望对你有一定的参考价值。

阅读目录

Go 语言 if else (条件判断)

Go 语言 中,if else 条件判断格式如下:

if 表达式1 
  分支1
 else if 表达式2 
  分支2
 else 
  分支3

①:当表达式 1 的结果为 true 时,会执行分支 1 的代码;
②:当表达式 1 的结果为 false 时,会执行表达式2,若结果为 true, 则会执行分支2的代码。
③:当前面的条件都不满足,即都为 false 时,会执行分支3的代码。

PS:表达式2、分支2 、分支3都是可选的,可以根据实际情况自行选择。

注意:Go 语言中规定:if 的 左括号 ‘’‘’ 必须与 if 表达式放在同一行,如果强行放置在其他位置,会发生如下编译错误。

下面是代码反例,编译报错图示:

同理,与 else 匹配的 “” 也必须与 else 放置在同一行, else 也必须与上一个 if 或 else if 的右边的大括号放在同一行。

Go 语言 if else 条件判断代码示例

下面是一段正确的 if else 条件判断示例:

package main

import "fmt"

func main() 
	// 定义一个字符串
	str := "wgchen.blog.csdn.net"

	// 获取该字符串的实际长度
	len := len(str)

	// 判断字符串的长度是否等于14
	if len == 14 
		// 若等于14
		fmt.Println("长度等于 14")
	 else 
		// 若不等于14
		fmt.Println("长度不等于 14")
	

PS E:\\golang\\src> go run .\\main.go
长度不等于 14
PS E:\\golang\\src>

if 的特殊写法

if 还有种特殊写法,我们可以在 if 表达式之前添加一个执行语句,再根据变量 进行判断,代码如下:

if err := Connect(); err != nil 
	fmt.Println(err)
	return

Connect() 是一个获取数据库连接的函数,它带有返回值,err := Connect() 是一个语句,执行 Connect() 函数后,将错误赋值给 err 变量。

err != nil 是 if 的条件判断表达式,当 err 不为空时,打印错误并返回。

这种写法可以将返回值和判断放在一行进行处理,使得返回值的作用域范围被限制在了 if else 语句组合中,这样做的好处是,变量的作用域范围越小,那么它可能造成的问题的可能性越小,这对代码的稳定性很有帮助,另外,也可以做炫技使用。

Go 语言 for(循环)

在 Go 语言 中,循环需要使用关键字 for 来完成,格式如下:

for 初始语句;条件表达式;结束语句 
  循环体代码

for 循环会不停地进行循环,直到 条件表达式 返回 false 才推出循环,即执行 for 循环 "" 后面的代码。

for 循环 - 初始语句

初始语句是第一次执行循环前执行的语句,通常情况下,我们会通过它来执行变量初始化操作。

注意: 通过初始语句声明的变量,作用域局限在 for 循环内。

代码如下:

package main

import "fmt"

func main() 
	for i := 0; i < 100; i++ 
		fmt.Println("知其黑,受其白 wgchen.blog.csdn.net")
	


上面代码打印了一百次知其黑,受其白 wgchen.blog.csdn.net。

另外,初始语句还可以忽略不写,但是初始语句后面的分号必须写,代码如下:

i := 0
for ; i < 100; i++ 
  fmt.Println("知其黑,受其白 wgchen.blog.csdn.net")

上面的代码中将 i 放在了 for 循环前面初始化,这时 i 的作用域不止作用在 for 循环内。

for 循环 - 条件表达式

每次在循环前,会计算条件表达式的值,如果结果为 true, 则继续循环;

否则将结束循环。

注意:条件表达式同样可以忽略不写,若不写,由于没有终止条件,则会陷入无限死循环,代码如下:

i := 0
for ; ; i++ 
  if i == 10 
    break
  

  fmt.Println("知其黑,受其白 wgchen.blog.csdn.net")

上面代码打印 10 次:知其黑,受其白 wgchen.blog.csdn.net

不是说死循环吗?
怎么只打印了 10 呢?

之所以只打印 10 次,因为循环体中有 if 判断语句,当 i 等于 10 时,执行了 break 结束循环的操作。

1 更美观的死循环写法

还有死循环的写法更具有可读性,代码如下:

i := 0
for 
  if i == 10 
    break
  

  fmt.Println("知其黑,受其白 wgchen.blog.csdn.net")

可以看到, for 后面直接忽略了初始语句、条件表达式以及结束语句。

2 只有一个条件的 for 循环

上面的代码还可以进一步简化,可以将 if 判断整合到 for 循环中,代码如下:

i := 0
for i <= 10 
  i++
  fmt.Println("知其黑,受其白 wgchen.blog.csdn.net")

将条件 i == 10 条件改成了 i <= 10, 并整合到 for 后面,若满足条件则会打印控制台,且每次对 i 执行自增加一操作。

for 循环 - 结束语句

在结束每次循环前被执行的语句。若循环被 break 、goto 、return 、panic 等语句强制退出,则结束语句不会被执行。

Go 语言 for range (键值循环)

Go 语言 中,我们还可以通过 for range 来遍历数组 、切片 、字符串 、map 以及通道(channel)。

for range 遍历数组、切片、字符串

通过 for range 遍历数组、切片、字符串的返回值都有一个规律:

  • 下标索引 index;
  • 下标对应的值 value;

下面代码演示了如何遍历切片,数组格式类似:

package main

import "fmt"

func main() 
	// 初始化一个切片
	slice := []int1, 2, 3, 4

	// 通过 for range 循环切片
	for index, value := range slice 
		fmt.Printf("index: %d, value: %d\\n", index, value)
	

PS E:\\golang\\src> go run .\\main.go
index: 0, value: 1
index: 1, value: 2
index: 2, value: 3
index: 3, value: 4
PS E:\\golang\\src>

下面代码演示了如何遍历字符串:

package main

import "fmt"

func main() 
	str := "知其黑,受其白 wgchen.blog.csdn.net"

	// 通过 for range 循环字符串
	for index, value := range str 
		fmt.Printf("index: %d, value: 0x%x\\n", index, value)
	


PS E:\\golang\\src> go run .\\main.go
index: 0, value: 0x77e5
index: 3, value: 0x5176
index: 6, value: 0x9ed1
index: 9, value: 0xff0c
index: 12, value: 0x53d7
index: 15, value: 0x5176
index: 18, value: 0x767d
index: 21, value: 0x20
index: 22, value: 0x77
index: 23, value: 0x67
index: 24, value: 0x63
index: 25, value: 0x68
index: 26, value: 0x65
index: 27, value: 0x6e
index: 28, value: 0x2e
index: 29, value: 0x62
index: 30, value: 0x6c
index: 31, value: 0x6f
index: 32, value: 0x67
index: 33, value: 0x2e
index: 34, value: 0x63
index: 35, value: 0x73
index: 36, value: 0x64
index: 37, value: 0x6e
index: 38, value: 0x2e
index: 39, value: 0x6e
index: 40, value: 0x65
index: 41, value: 0x74
PS E:\\golang\\src>

上面代码中的 value 变量实际类型是 runne, 本质上是 int32, 以十六进制格式打印出来的是字符串编码。

for range 遍历 map 字典

通过 for range 遍历 map 字典会返回键和值,称为键值对,它们总是一对一出现,演示代码如下:

package main

import "fmt"

func main() 
	m := map[int]string
		1: "知其黑,受其白",
		2: "wgchen.blog.csdn.net",
	

	for key, value := range m 
		fmt.Printf("key: %d, value: %s\\n", key, value)
	

PS E:\\golang\\src> go run .\\main.go
key: 1, value: 知其黑,受其白
key: 2, value: wgchen.blog.csdn.net
PS E:\\golang\\src>

注意: 对 map 字典进行遍历时,遍历出的键值对是无序的,如果需要有序输出,需要先排序。

for range 遍历通道(channel)

for range 遍历通道(channel)有点不同,此时只会输出一个值,即管道内的类型对应的数据

下面代码演示了如何遍历通道(channel):

package main

import "fmt"

func main() 

	// 初始化一个通道
	c := make(chan int)

	// 启动一个 goroutine, 功能是往通道中推送数据 1、2、3,然后关闭通道
	go func() 
		c <- 1
		c <- 2
		c <- 3
		close(c)
	()

	for value := range c 
		fmt.Println(value)
	

注意: goroutine 在启动结束后,会被立刻并行执行。关于 goroutine,后面小节会详细介绍,这里只做了解。

PS E:\\golang\\src> go run .\\main.go
1
2
3
PS E:\\golang\\src>

for range 中使用匿名变量

假设说在 for range 遍历中只想获取下标索引,或者是值要怎么做呢?

比较优雅的写法是通过匿名变量。

什么是匿名变量?

1、它可以理解成一种占位符;
2、这种变量不会分配内存,也不会占用变量名;
3、在 for range 中,可以通过匿名变量接受键 key,也可以接受值 value。

下面代码演示了如果通过匿名变量来接受 key, 循环体中只打印了值 value。

package main

import "fmt"

func main() 
	m := map[int]string
		1: "知其黑,受其白",
		2: "wgchen.blog.csdn.net",
	

	for _, value := range m 
		fmt.Printf("value: %s\\n", value)
	

PS E:\\golang\\src> go run .\\main.go
value: 知其黑,受其白
value: wgchen.blog.csdn.net
PS E:\\golang\\src>

Go 语言 switch 语句(分支判断)

分支判断可以理解成批量的 if 语句,使用 switch 语句可以非常方便地对大量值进行条件判断。

1 基本写法

Go 语言 改进了其他语言中 switch 语句的设计弊端。Go 语言中 switch 中的每一个 case 都是独立代码块,无需通过 break 语句跳出代码块,以避免执行到下一个 case 代码块。

PS: 如果你有其他语言的编程经验 (如 Java), 一定会对 case 代码块中的 break 语句印象深刻。

swtich 语句的基本格式如下:

package main

import "fmt"

func main() 
	num := 1

	switch num 
	case 1:
		fmt.Println("1 -> 知其黑 wgchen")
	case 2:
		fmt.Println("2 -> 受其白 blog.csdn.net")
	default:
		fmt.Println("error")
	

PS E:\\golang\\src> go run .\\main.go
1 -> 知其黑 wgchen
PS E:\\golang\\src>

上面代码中,case 对整型 num 进行判断,若条件符合,则打印相应的字符串 。

另外,还使用了 default 分支,default 分支表示若条件均不符合,则执行改代码块。

注意:每一个 swtich 语句中只能有一个 default 分支。

2 一分支多值

当需要多个 case 放在一起的时候,代码格式如下:

package main

import "fmt"

func main() 
	num := 1

	switch num 
	case 1, 2:
		fmt.Println("知其黑 blog.csdn.net")
	


PS E:\\golang\\src> go run .\\main.go
知其黑 blog.csdn.net
PS E:\\golang\\src>

表达式直接用逗号 , 隔开即可。

3 分支表达式

case 后面除了定义常量以外,还可以像 if 语句一样添加表达式,代码如下:

package main

import "fmt"

func main() 
	num := 1

	switch 
	case num > 0 && num < 2:
		fmt.Println("知其黑 blog.csdn.net")
	

S E:\\golang\\src> go run .\\main.go
知其黑 blog.csdn.net
PS E:\\golang\\src>

注意: 这个时候,switch 后面不再跟判断变量,直接不写即可。

4 fallthrough 关键字 —— 兼容 C 语言的 case 设计

前面说到了 Go 语言中 swtich 语句中的 case 均为独立代码块,执行完成后,不会像 C 语言那种继续执行下一个 case。

但是为了兼容一些移植代码,Go 语言加入了 fallthrough 关键字来实现这一功能。

实例代码如下:

package main

import "fmt"

func main() 
	num := 1

	switch 
	case num > 0:
		fmt.Println("知其黑,受其白 wgchen.blog.csdn.net")
		fallthrough
	case num < 2:
		fmt.Println("知其黑,受其白 wgchen.blog.csdn.net")
	

PS E:\\golang\\src> air

  __    _   ___
 / /\\  | | | |_)
/_/--\\ |_| |_| \\_ , built with Go

watching .
watching resources
watching resources\\views
watching resources\\views\\articles
!exclude tmp
building...
running...
知其黑,受其白 wgchen.blog.csdn.net
知其黑,受其白 wgchen.blog.csdn.net

Go 语言 goto 语句(代码跳转)

在 Go 语言 中,goto 语句通过标签实现代码间的跳转。
它通常会被使用在快速跳出循环 、避免定义重复代码等。

1 使用 goto 跳出循环

package main

import "fmt"

func main() 
	// 外循环
	for i := 0; i < 10; i++ 
		// 内循环
		for j := 0; j < 10; j++ 
			// 当 j 等于 2 时,跳转到标签 breakHere 那里
			if j == 2 
				// 跳转标签
				goto breakHere
			
		
	

	// 手动返回,防止执行后面的标签
	return

	// 定义一个标签
breakHere:
	fmt.Println("跳到这里 ...")

building...
running...
跳到这里 ...

2 避免定义重复代码

在实际的编码中,经常会定义一些重复性的代码,如下:


上面的这段明显有重复代码,我们可以 goto 定义标签来使代码变的更加优雅一点:

Go 语言 break 语句(跳出循环)

在 Go 语言 中,break 语句可以结束 for 、switch 和 select 代码块。

下面代码演示了 break 语句跳出单层循环:

package main

import "fmt"

func main() 
	// 外循环
	for i := 0; i < 10; i++ 
		fmt.Printf("i: %d\\n", i)

		// 当 i 等于 6 时,跳转到循环
		if i == 6 
			// 跳出循环
			break
		
	

	fmt.Println("跳出循环 ...")

i: 0
i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
跳出循环 ...

上面代码,当循环到 6 时,通过 break 语句跳出循环。

break 跳出代码块 - 退出多层循环

通过 break 语句搭配标签可以跳出代码块,如跳出 for 、switch 和 select 代码块。

下面的代码演示了如何通过 break 跳出多层循环,代码如下:

package main

import "fmt"

func main() 

OuterLoop:
	// 外循环
	for i := 0; i < 10; i++ 
		fmt.Printf("i: %d\\n", i)

		// 内循环
		for j := 0; j < 10; j++ 
			fmt.Printf("j: %d\\n", j)
			if i == 0 && j == 6 
				// 跳出 OuterLoop 代码块
				break OuterLoop
			
		
	

	fmt.Println("跳出循环 ...")

Go 语言 continue 语句(继续下次循环)

在 Go 语言 中,continue 语句可以结束当前 for 循环 ,进入下一次 for 循环, 代码如下:

package main

import "fmt"

func main() 

	for i := 0; i < 10; i++ 
		// 当 i 等于 2 时,执行 continue 语句,继续下一次循环
		if i == 2 
			continue
		

		fmt.Printf("i: %d\\n", i)
	

running...
i: 0
i: 1
i: 3
i: 4
i: 5
i: 6
i: 7
i: 8
i: 9

可以看到并没有打印 2, 那是因为当循环到 i 等于 2 时,直接执行了 continue 语句,继续了下一循环。

另外,我们还可以在 continue 语句后添加标签,表示开始标签处的循环:

package main

import "fmt"

func main() 

OuterLoop:
	// 外循环
	for i := 0; i < 3; i++ 
		// 内循环
		for j := 0; j < 3; j++ 
			// 当 j 等于 1 时,执行 continue 语句跳转到 OuterLoop 标签处,即跳出至外循环,而不是内循环
			if j == 1 
				continue OuterLoop
			
			fmt.Printf("i: %d, j: %d\\n", i, j)
		
	

building...
running...
i: 0, j: 0
i: 1, j: 0
i: 2, j: 0

代码中,当 j 等于 1 时,会执行 continue 语句直接跳转到 OuterLoop 标签处,即跳出至外循环继续,而不是内循环。

参考文献

Golang 【basic_leaming】流程控制

以上是关于Golang basic_leaming3 流程控制的主要内容,如果未能解决你的问题,请参考以下文章

Golang basic_leaming流程控制

Golang basic_leaming流程控制

Golang basic_leaming反射

Golang basic_leaming反射

Golang basic_leaming结构体

Golang basic_leaming结构体