# 1.10 流程控制:for 循环
Go里的流程控制方法还是挺丰富,整理了下有如下这么多种:
- if - else 条件语句
- switch - case 选择语句
- for - range 循环语句
- goto 无条件跳转语句
- defer 延迟执行
上一篇讲了switch - case 选择语句,今天先来讲讲 for 循环语句。
## 0. 语句模型
这是 for 循环的基本模型。
```
for [condition | ( init; condition; increment ) | Range]
{
statement(s);
}
```
可以看到 for 后面,可以接三种类型的表达式。
1. 接一个条件表达式
2. 接三个表达式
3. 接一个 range 表达式
但其实还有第四种
4. 不接表达式
## 1. 接一个条件表达式
这个例子会打印 1 到 5 的数值。
```go
a := 1
for a <= 5 {
fmt.Println(a)
a ++
}
```
输出如下
```
1
2
3
4
5
```
## 2. 接三个表达式
for 后面,紧接着三个表达式,使用 `;` 分隔。
这三个表达式,各有各的用途
- 第一个表达式:初始化控制变量,在整个循环生命周期内,只运行一次;
- 第二个表达式:设置循环控制条件,当返回true,继续循环,返回false,结束循环;
- 第三个表达式:每次循完开始(除第一次)时,给控制变量增量或减量。
这边的例子和上面的例子,是等价的。
```go
import "fmt"
func main() {
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
}
```
输出如下
```
1
2
3
4
5
```
## 2. 不接表达式:无限循环
在 Go 语言中,没有 while 循环,如果要实现无限循环,也完全可以 for 来实现。
当你不加任何的判断条件时, 就相当于你每次的判断都为 true,程序就会一直处于运行状态,但是一般我们并不会让程序处于死循环,在满足一定的条件下,可以使用关键字 `break` 退出循环体,也可以使用 `continue` 直接跳到下一循环。
下面两种写法都是无限循环的写法。
```go
for {
代码块
}
// 等价于
for ;; {
代码块
}
```
举个例子
```go
import "fmt"
func main() {
var i int = 1
for {
if i > 5 {
break
}
fmt.Printf("hello, %d\n", i)
i++
}
}
```
输出如下
```
hello, 1
hello, 2
hello, 3
hello, 4
hello, 5
```
## 3. 接 for-range 语句
遍历一个可迭代对象,是一个很常用的操作。在 Go 可以使用 for-range 的方式来实现。
range 后可接数组、切片,字符串等
由于 range 会返回两个值:索引和数据,若你后面的代码用不到索引,需要使用 `_` 表示 。
```go
import "fmt"
func main() {
myarr := [...]string{"world", "python", "go"}
for _, item := range myarr {
fmt.Printf("hello, %s\n", item)
}
}
```
输出如下
```
hello, world
hello, python
hello, go
```
如果你用一个变量来接收的话,接收到的是索引
```go
import "fmt"
func main() {
myarr := [...]string{"world", "python", "go"}
for i := range myarr {
fmt.Printf("hello, %v\n", i)
}
}
```
输出如下
```
hello, 0
hello, 1
hello, 2
```
---
- 第一章:基础知识
- 1.1 一文搞定开发环境的搭建
- 1.2 五种变量创建的方法
- 1.3 数据类型:整型与浮点型
- 1.4 数据类型:byte、rune与字符串
- 1.5 数据类型:数组与切片
- 1.6 数据类型:字典与布尔类型
- 1.7 数据类型:指针
- 1.8 流程控制:if-else
- 1.9 流程控制:switch-case
- 1.10 流程控制:for 循环
- 1.11 流程控制:goto 无条件跳转
- 1.12 流程控制:defer 延迟语句
- 1.13 流程控制:理解 select 用法
- 1.14 异常机制:panic 和 recover
- 1.15 语法规则:理解语句块与作用域
- 第二章:面向对象
- 2.1 面向对象:结构体与继承
- 2.2 面向对象:接口与多态
- 2.3 面向对象:结构体里的 Tag 用法
- 2.4 学习接口:详解类型断言
- 2.5 学习接口:Go 语言中的空接口
- 2.6 学习接口:接口的三个"潜规则"
- 2.7 学习反射:反射三定律
- 2.8 学习反射:全面学习反射的函数
- 2.9 详细图解:静态类型与动态类型
- 2.10 关键字:make 和 new 的区别?
- 第三章:项目管理
- 3.1 依赖管理:包导入很重要的 8 个知识点
- 3.2 依赖管理:超详细解读 Go Modules 应用
- 3.3 开源发布:如何开源自己写的包给别人用?
- 3.4 代码规范:Go语言中编码规范
- 第四章:并发编程
- 4.1 学习 Go 函数:理解 Go 里的函数
- 4.2 学习 Go 协程:goroutine
- 4.3 学习 Go 协程:详解信道/通道
- 4.4 学习 Go 协程:WaitGroup
- 4.5 学习 Go 协程:互斥锁和读写锁
- 4.7 学习 Go 协程: 信道死锁经典错误案例
- 4.7 学习 Go 协程:如何实现一个协程池?
- 4.8 理解 Go 语言中的 Context
- 4.9 学习一些常见的并发模型
- 第五章:学标准库
- 5.1 fmt.Printf 方法详解
- 5.2 os/exec 执行命令的五种姿势
- 第六章:开发技能
- 6.1 Go 命令:go test 工具详解
- 6.2 单元测试:如何进行单元测试?
- 6.3 调试技巧:使用 GDB 调试 Go 程序
- 6.4 Go 命令: Go 命令指南
- 第七章:暂未分类
- 7.1 20 个学习 Go 语言的精品网站
