golang-study/notes/3.运算符、流程控制篇.md
2021-09-11 18:30:18 +08:00

457 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

**本章目录:**
**0x02 Go语言基础之运算符**
1.分类说明
2.算术运算符
3.关系运算符
4.逻辑运算符
5.位运算符
6.赋值运算符
**0x03 Go语言基础之流程控制**
1.if else(分支结构)
if条件判断基本写法
if条件判断特殊写法
2.for(循环结构)
3.for range(键值循环)
4.switch case(选择语句)
5.goto(跳转到指定标签)
6.break(跳出循环)
7.continue(继续下次循环)
![img](assets/4aa545dccf7de8d4a93c2b2b8e3265ac0a26d216.png@progressive.webp)
# 0x02 Go语言基础之运算符
**什么是运算符?**
> 答: 运算符用于在程序运行时执行数学或逻辑运算。
# 1.分类说明
描述: 与其他编程语言类似 Go 语言内置的运算符有如下几种
\- 1. 算术运算符
\- 2. 关系运算符
\- 3. 逻辑运算符
\- 4. 位运算符
\- 5. 赋值运算符
# 2.算术运算符
![img](assets/6b536e2396cd0da41aa7e26d9c1a2f9cacecdb74.png@288w_446h_progressive.webp)
**注意:** `++`(自增)和`--`自减在Go语言中是单独的语句并不是运算符。
# 3.关系运算符
![img](assets/6ac4a9e0b61cd0685e7ca10670986601d4275669.png@942w_551h_progressive.webp)
Tips : Go 语言是强类型的所以必须相同类型变量才能进行比较。
# 4.逻辑运算符
![img](assets/87cb44700a637253cb3fdb0a2fb2c0d65736a603.png@942w_399h_progressive.webp)
# 5.位运算符
描述: 位运算符对整数在内存中的二进制位进行操作。
![img](assets/fed8f7e698d83114c8224e3823c6f8e031e8962d.png@942w_515h_progressive.webp)
# 6.赋值运算符
![img](assets/775cbe23ce1a1ce9ea9cb5ac0290a35aac9e5f95.png@908w_882h_progressive.webp)
**示例演示:**
```go
a += 1 // a = a + 1
a %= 3 // a = a % 3
a <<= 4 // a = a << 4
a ^= 5 // a = a ^ 5
```
# 0x03 Go语言基础之流程控制
**Q: 什么是流程控制**
> 流程控制是每种编程语言控制逻辑走向和执行次序的重要部分,流程控制可以说是一门语言的“经脉”。
Tips : Go语言中最常用的流程控制有`if`和`for`,而`switch`和`goto`主要是为了简化代码、降低重复代码而生的结构,属于扩展类的流程控制。
# 1.if else(分支结构)
# if条件判断基本写法
描述: Go语言中`if`条件判断的格式如下:
```go
if 表达式1 {
分支1
} else if 表达式2 {
分支2
} else{
分支3
}
```
当表达式1的结果为`true`时执行分支1否则判断表达式2如果满足则执行分支2都不满足时则执行分支3。 if判断中的`else if`和`else`都是可选的,可以根据实际需要进行选择。
Go语言规定与`if`匹配的左括号`{`必须与`if和表达式`放在同一行,`{`放在其他位置会触发编译错误。 同理,与`else`匹配的`{`也必须与`else`写在同一行,`else`也必须与上一个`if`或`else if`右边的大括号在同一行。
示例1:
```go
func ifDemo1() {
score := 65
if score >= 90 {
fmt.Println("A")
} else if score > 75 {
fmt.Println("B")
} else {
fmt.Println("C") // 输出结果
}
}
```
# if条件判断特殊写法
描述: if条件判断还有一种特殊的写法可以在 if 表达式之前添加一个执行语句,再根据变量值进行判断,举个例子:
示例2
```go
func ifDemo2() {
score := 88 // 注意变量作用域的影响
if score := 65; score >= 90 {
fmt.Println("A", score)
} else if score > 75 {
fmt.Println("B", score)
} else {
fmt.Println("C", score) // 输出结果
}
fmt.Println("score : ", score)
}
```
执行结果:
```go
C 65
score : 88
```
**思考题:** 上下两种写法的区别在哪里?
> 答: 上述 示例1 与 示例2 区别在于定义 score 变量位置得不同, 示例1中的score变量在函数代码块中有效, 而示例2中的score变量作用域只在`if...else`代码块中有效。
# 2.for(循环结构)
描述: Go 语言中的所有循环类型均可以使用`for`关键字来完成。
for循环的基本格式如下
```go
for 初始语句;条件表达式;结束语句{
循环体语句
}
```
条件表达式返回`true`时循环体不停地进行循环,直到条件表达式返回`false`时自动退出循环。
func forDemo() { for i := 0; i < 10; i++ { fmt.Println(i) }}
for循环的初始语句可以被忽略但是初始语句后的分号必须要写例如
func forDemo2() { i := 0 for ; i < 10; i++ { fmt.Println(i) }}
for循环的初始语句和结束语句都可以省略例如
func forDemo3() { i := 0 for i < 10 { fmt.Println(i) i++ }}
for无限循环这种写法类似于其他编程语言中的`while``while`后添加一个条件表达式满足条件表达式时持续循环否则结束循环
例如: for循环可以通过`break`、`goto`、`return`、`panic`语句强制退出循环
```go
for {
循环体语句
}
```
# 3.for range(键值循环)
描述: Go语言中可以使用`for range`遍历数组切片字符串map 及通道channel)。
通过`for range`遍历的返回值有以下规律
\* 1. 数组切片字符串返回索引和值
\* 2. map返回键和值
\* 3. 通道channel只返回通道内的值
**
**
**简单示例:**
```go
s1 := "Hello,Go 输出的是中文"
for i, v := range s1 {
fmt.Printf("Index : %d ,Value : %s , Number : %v \n", i, string(v), v)
}
```
**输出结果:**
```go
Index : 0 ,Value : H , Number : 72
Index : 1 ,Value : e , Number : 101
Index : 2 ,Value : l , Number : 108
Index : 3 ,Value : l , Number : 108
Index : 4 ,Value : o , Number : 111
Index : 5 ,Value : , , Number : 44
Index : 6 ,Value : G , Number : 71
Index : 7 ,Value : o , Number : 111
Index : 8 ,Value : , Number : 32
Index : 9 ,Value : , Number : 36755
Index : 12 ,Value : , Number : 20986
Index : 15 ,Value : , Number : 30340
Index : 18 ,Value : , Number : 26159
Index : 21 ,Value : , Number : 20013
Index : 24 ,Value : , Number : 25991
```
# 4.switch case(选择语句)
描述: 使用`switch`语句可方便地对大量的值进行条件判断即简化大量判断
```go
func switchDemo1() {
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("无效的输入!")
}
}
```
Go语言规定每个`switch`只能有一个`default`分支, 但一个分支可以有多个值多个case值中间使用英文逗号分隔
```go
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)
}
}
```
分支还可以使用表达式这时候switch语句后面不需要再跟判断变量例如
```go
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("活着真好")
}
}
```
`fallthrough`语法: 可以执行满足条件的case的下一个case是为了兼容C语言中的case设计的值得学习)。
```go
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("...")
}
}
```
结果输出:
a b
# 5.goto(跳转到指定标签)
描述: `goto`语句通过标签进行代码间的无条件跳转。`goto`语句可以在快速跳出循环避免重复退出上有一定的帮助, Go语言中使用`goto`语句能简化一些代码的实现过程
例如:双层嵌套的for循环要退出时
```go
func gotoDemo1() {
var breakFlag bool
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
// 设置退出标签
breakFlag = true
break
}
fmt.Printf("%v-%v\n", i, j)
}
// 外层for循环判断
if breakFlag {
break
}
}
}
```
使用`goto`语句能简化代码
```go
func gotoDemo2() {
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
// 设置退出标签
goto breakTag
}
fmt.Printf("%v-%v\n", i, j)
}
}
return
// 标签
breakTag:
fmt.Println("正结束for循环")
fmt.Println("已结束for循环")
}
```
执行结果:
```go
0-0
0-1
正结束for循环
已结束for循环
```
# 6.break(跳出循环)
描述: `break`语句可以结束`for`、`switch``select`的代码块
`break`语句还可以在语句后面添加标签表示退出某个标签对应的代码块标签要求必须定义在对应的`for`、`switch` `select`的代码块上 举个例子
```go
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("...")
}
```
# 7.continue(继续下次循环)
描述: `continue`语句可以结束当前循环开始下一次的循环迭代过程仅限在`for`循环内使用
`continue`语句后添加标签时表示开始标签对应的循环例如
```go
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)
}
}
}
```