一、条件判断
1. 条件判断简介
条件语句是用来判断给定的条件是否满足(表达式值是否为true或者false),并根据判断的结果决定执行情况的语句。go语言中的条件语句主要包含如下几种情况:
- if - else if - else 语句:
if
语句由一个布尔表达式后紧跟一个或多个语句组成,语句后可以使用可选的else
和else if
语句, 这些语句中的表达式在布尔表达式的值和if
语句后布尔表达式的值不同时执行;可以在if
或else if
语句中嵌入一个或多个if
或else if
语句。 - switch 语句:
switch
语句用于基于不同条件执行不同动作。 - select 语句:
select
语句类似于switch
语句,但是select
会随机执行一个可运行的case
。如果没有case
可运行,它将阻塞,直到有case
可运行。
在 go 语言中使用 if
时需要注意以下几点:
- 不需使用括号将条件包含起来。
- 大括号
{}
必须存在,即使只有一行语句。 - 左括号必须在
if
或else
的同一行。 - 在
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
语句可以结束 for
、switch
和 select
的代码块。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
语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的 for
、switch
和 select
的代码块上。
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~")
}