Golang 流程控制

一、条件判断

1. 条件判断简介

条件语句是用来判断给定的条件是否满足(表达式值是否为true或者false),并根据判断的结果决定执行情况的语句。go语言中的条件语句主要包含如下几种情况:

  • if - else if - else 语句:if 语句由一个布尔表达式后紧跟一个或多个语句组成,语句后可以使用可选的 elseelse if 语句, 这些语句中的表达式在布尔表达式的值和 if 语句后布尔表达式的值不同时执行;可以在 ifelse if 语句中嵌入一个或多个 ifelse if 语句。
  • switch 语句: switch 语句用于基于不同条件执行不同动作。
  • select 语句: select 语句类似于 switch 语句,但是 select 会随机执行一个可运行的 case。如果没有 case 可运行,它将阻塞,直到有 case 可运行。

在 go 语言中使用 if 时需要注意以下几点:

  • 不需使用括号将条件包含起来。
  • 大括号{}必须存在,即使只有一行语句。
  • 左括号必须在ifelse的同一行。
  • if之后,条件语句之前,可以添加变量初始化语句,使用进行分隔。

在 go 语言中使用 switch 时需要注意以下几点:

  • 支持多条件匹配。
  • 不同的 case 之间不使用 break 分隔,默认只会执行一个 case
  • 如果想要执行多个 case,需要使用 fallthrough 关键字,也可用 break 终止。
  • 分支还可以使用表达式。

2. if 语句的使用

2.1 if 语句

go语言中 if 语句的语法如下:

// 当表达式1的结果为true时,执行分支1,否则判断表达式2,如果满足则执行分支2,都不满足时,则执行分支3
if 表达式1 {
    分支1
} else if 表达式2 {
    分支2
} else{
    分支3
}

示例1:满足条件则执行,否则跳过。

package main

import "fmt"

func main() {

	age := 20

	if age >= 18 {
		fmt.Println("你已经成年了")
	}

	fmt.Printf("程序运行结束")
}

示例2:初始变量可以声明在布尔表达式里面,但是只在判断中生效。

package main

import "fmt"

func main() {
	if age := 20; age >= 18 {
		fmt.Println("你已经成年了")
	}

	fmt.Printf("程序运行结束")

	fmt.Println(age)  // undefined: age
}

示例3:不能使用0或非0表示真假。

package main

import "fmt"

func main() {
	var i = 1
	if i {       // 编译失败
		fmt.Println("here")
	}
	fmt.Printf("程序运行结束")
}
2.2 if-else 语句

go语言中 if-else 语句的语法如下:

if 布尔表达式 {
   /* 在布尔表达式为 true 时执行 */
} else {
  /* 在布尔表达式为 false 时执行 */
}

示例1:判断奇数偶数。

package main

import (
	"fmt"
)

func main() {
	var num int

	fmt.Println("输入一个数字:")
	fmt.Scan(&num)
	fmt.Printf("s 的值是:%v \n", num)

	if num%2 == 0 {
		fmt.Println("偶数")
	} else {
		fmt.Print("奇数")
	}
}

示例2:判断是否成年。

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	// 生成一个 1~100 随机数
	rand.Seed(time.Now().UnixNano())
	age := rand.Intn(100)

	if age >= 18 {
		fmt.Println("你已经成年")
	} else {
		fmt.Println("你还未成年")
	}
}

示例3:初始变量可以声明在布尔表达式里面,但是只在判断中生效。

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	// 生成一个 1~100 随机数
	rand.Seed(time.Now().UnixNano())

	if age := rand.Intn(100); age >= 18 {
		fmt.Println("你是成年人")
	} else {
		fmt.Println("你还未成年")
	}

	//fmt.Println(age)  age 作用域只在布尔表达式中
}
2.3 if-else if-else 语句

go语言中 if-else if-else 语句的语法如下:

if 布尔表达式1 {
    // do something
} else if 布尔表达式2 {
    // do something else
}else {
    // catch-all or default
}

示例1:根据分数划分等级

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	// 生成一个 1~100 随机数
	rand.Seed(time.Now().UnixNano())
	score := rand.Intn(100)
	
	if score >= 60 && score <= 70 {
		fmt.Println("C")
	} else if score > 70 && score <= 90 {
		fmt.Println("B")
	} else {
		fmt.Println("A")
	}
}

示例2:初始变量可以声明在布尔表达式里面,但是只在判断中生效。

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	// 生成一个 1~100 随机数
	rand.Seed(time.Now().UnixNano())

	if score := rand.Intn(100); score >= 60 && score <= 70 {
		fmt.Println("C")
	} else if score > 70 && score <= 90 {
		fmt.Println("B")
	} else {
		fmt.Println("A")
	}

	//fmt.Println(score)  score 作用域只在布尔表达式中
}

示例3:输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续判断第二个字母

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	var c string
	fmt.Println("输入一个字符:")
	fmt.Scan(&c)

	if c == "S" {
		fmt.Println("输入第二个字符:")
		fmt.Scan(&c)
		if c == "a" {
			fmt.Println("Saturday")
		} else if c == "u" {
			fmt.Println("Sunday")
		} else {
			fmt.Println("输入错误")
		}
	} else if c == "F" {
		fmt.Println("Friday")
	} else if c == "M" {
		fmt.Println("Monday")
	} else if c == "T" {
		fmt.Println("输入第二个字符:")
		fmt.Scan(&c)
		if c == "u" {
			fmt.Println("Tuesday")
		} else if c == "h" {
			fmt.Println("Thursday")
		} else {
			fmt.Println("输入错误")
		}
	} else if c == "W" {
		fmt.Println("Wednesday")
	} else {
		fmt.Println("输入错误")
	}
}
2.4 if 语句嵌套使用

go语言中 if 语句也可以嵌套使用,语法如下:

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

示例:比较三个数的大小

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	rand.Seed(time.Now().UnixNano())

	a := rand.Intn(100)
	b := rand.Intn(100)
	c := rand.Intn(100)

	fmt.Printf("随机生成数字a的值为:%v \n", a)
	fmt.Printf("随机生成数字b的值为:%v \n", b)
	fmt.Printf("随机生成数字c的值为:%v \n", c)

	if a > b {
		if a > c {
			fmt.Println("a最大")
		}
	} else {
		if b > c {
			fmt.Println("b最大")
		} else {
			fmt.Println("c最大")
		}
	}
}

3. switch 语句的使用

3.1 基本使用

switch 语句会执行满足条件的 case 分支,如果所有的 case 都未命中,则会执行 default 分支 。Go语言规定每个 switch 只能有一个 default 分支。

package main

import (
	"fmt"
)

func main() {
	finger := 3
	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("无效的输入!")
	}
}
3.2 初始变量声明

初始变量可以声明在布尔表达式里面,但是作用域只有 switch 代码段 。

package main

import (
	"fmt"
)

func main() {
	switch finger := 3; finger {
	case 1:
		fmt.Println("大拇指")
	case 2:
		fmt.Println("食指")
	case 3:
		fmt.Println("中指")
	case 4:
		fmt.Println("无名指")
	case 5:
		fmt.Println("小拇指")
	default:
		fmt.Println("无效的输入!")
	}
    
    //fmt.Println(finger) // undefined: finger
}
3.3 分支可以有多个值

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

package main

import (
	"fmt"
)

func main() {
	switch n := 7; n {
	case 1, 3, 5, 7, 9:
		fmt.Println("奇数")
	case 2, 4, 6, 8:
		fmt.Println("偶数")
	default:
		fmt.Println(n)
	}
}
3.4 分支的值可以是表达式

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

package main

import (
	"fmt"
)

func main() {
	age := 30
	switch {
	case age < 25:
		fmt.Println("好好学习吧")
	case age > 25 && age < 35:
		fmt.Println("好好工作吧")
	case age > 60:
		fmt.Println("好好享受吧")
	default:
		fmt.Println("活着真好")
	}
}
3.5 fallthrough 的使用

fallthrough 语法可以执行满足条件的 case 的下一个 case

package main

import (
	"fmt"
)

func main() {
	s := "a"
	switch {
	case s == "a":
		fmt.Println("a")
		fallthrough
	case s == "b":
		fmt.Println("b")
		fallthrough
	case s == "c":
		fmt.Println("c")
	default:
		fmt.Println("...")
	}
}

二、循环

go 语言中的所有循环类型均可以使用 for 关键字来完成。条件表达式返回true时循环体不停地进行循环,直到条件表达式返回false时自动退出循环。

1. for 语句

go语言中 for 语句的语法如下:

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

示例1:基本使用,输出 1~10

package main

import "fmt"

func main() {
	for i := 1; i <= 10; i++ {
		fmt.Printf("i: %v \n", i)
	}
}

示例2:for 循环的初始语句可以写在外面,但是初始语句后的分号必须要写

package main

import "fmt"

func main() {
    i := 1
	for ; i <= 10; i++ {
		fmt.Printf("i: %v \n", i)
	}
}

示例3:初始条件和结束条件都可以省略(结束条件可以写在循环体中)

package main

import "fmt"

func main() {
	i := 1
	for i <= 10 {
		fmt.Printf("i: %v \n", i)
		i ++  // 结束条件
	}
}

示例4:无限循环

package main

import "fmt"

func main() {
    // 条件永远满足
	i := 1
	for i <= 10 {
		fmt.Printf("i: %v \n", i)
	}
    
    // 或者直接写一个for关键字
    for {
        fmt.Println("我一直在执行~")
    }
}

2. for range 语句

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

  • 数组、切片、字符串返回索引和值
  • map返回键和值。
  • 通道(channel)只返回通道内的值。
package main

import "fmt"

func main() {
	
    s := "hello南京"
    
    // 普通方式遍历字符串是按照单个字节遍历
	for i := 0; i < len(s); i++ { //byte
		fmt.Printf("%v(%c) ", s[i], s[i]) // 104(h) 101(e) 108(l) 108(l) 111(o) 229(å) 141() 151(—) 228(ä) 186(º) 172(¬) 
	}
	// 使用 for + range 遍历字符串,可以正常遍历出中文
    for _, r := range s { 
		fmt.Printf("%v(%c) ", r, r)  // 104(h) 101(e) 108(l) 108(l) 111(o) 21335(南) 20140(京) 
	}
}

三、流程控制关键字

1. break 关键字

break 语句可以结束 forswitchselect 的代码块。Go 语言中使用 break 要注意以下几点:

  • 单独在 select 中使用 break 和不使用 break 没有区别。
  • switch 语句中,如果没有使用 fallthough,使用 break 和不使用 break 没有区别;如果有 fallthough,使用 break 能够终止 fallthough 后面的 case 语句的执行。
  • 带标签的 break ,可以直接跳出多层循环的作用域,不需要使用控制变量一层一层跳出循环,没有带 break 的只能跳出当前语句块。
1.1 跳出for循环
package main

import "fmt"

func main() {

	for i := 1; i <= 10; i++ {
		if i == 5 {
			break
		}
        
		fmt.Println(i)  // 输出 1 2 3 4
	}
}
1.2 跳出switch循环
package main

import "fmt"

func main() {
	i := 2
	switch i {
	case 1:
		fmt.Println("等于1")
		break
	case 2:
		fmt.Println("等于2")
		break  // 满足条件后直接退出switch。break后所有代码都不会执行
		fallthrough
	case 3:
		fmt.Println("等于3")
		break
	default:
		fmt.Println("不关心")
		break
	}
}
1.3 带标签的break

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

package main

import "fmt"

func main() {

	for i := 0; i <= 10; i++ {
		for j := 0; j <= 10; j++ {
			if j == 5 {
				break  // 只能退出里层的j循环,外层的i循环还是会继续执行
			}

			fmt.Printf("j: %v\n", j)
		}

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


breakKey:
	for i := 0; i <= 10; i++ {
		for j := 0; j <= 10; j++ {
			if j == 5 {
				break breakKey  // 可以退出两层循环
			}

			fmt.Printf("j: %v\n", j)
		}

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

2. continue 关键字

continue 在 Go 中只能用在 for 循环中,它可以终止本次循环,直接进行下一次循环。

package main

import "fmt"

func main() {

	for i := 0; i <= 10; i++ {
		if i == 2 {
			continue  // 遇到i等于2时,直接跳过,开始下一次循环。continue后的代码不会执行
		}

		fmt.Println(i)
	}
}

continue 后也可以添加标签,表示退出标签对应的本次循环的代码块,继续开始下一次循环:

package main

import "fmt"

func main() {
forLoop1:
	for i := 0; i <= 5; i++ {
		//forLoop2:
		for j := 0; j <= 5; j++ {
			if i == 2 && j == 2 {
				continue forLoop1 // 当i和j都等于2时,跳过当前的j循环和i循环,直接开始循环i=3
			}

			fmt.Printf("i: %v, j: %v\n", i, j)
		}
	}
}

3. goto 关键字

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

示例:当 j==2 时退出双层循环

package main

import "fmt"

func main() {
	// 可以通过标识位来判断是否要退出外层循环
	exitFlag := false

	for i := 0; i <= 5; i++ {
		for j := 0; j <= 5; j++ {
			if j == 2 {
				exitFlag = true
				break
			}
			fmt.Printf("i: %v, j: %v\n", i, j)
		}

		if exitFlag {
			break
		}
	}
}

可以使用 goto + 标签 来优化代码:

package main

import "fmt"

func main() {

	for i := 0; i <= 5; i++ {
		for j := 0; j <= 5; j++ {
			if j == 2 {
				goto exitFlag  // 直接跳转到标签对应的代码段处
			}
			fmt.Printf("i: %v, j: %v\n", i, j)
		}
	}

exitFlag:
	fmt.Println("end~")
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值