for 循环
go 里面的循环只有一个 for 循环
for 循环有下面四种方式的写法
第一种方式,for 后面什么都不写
死循环,在代码中,如果一个 for 循环没有结束条件,则代码会陷入死循环
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("开始")
for { // 死循环了,没有结束条件
fmt.Println("红鲤鱼与绿鲤鱼与驴")
time.Sleep(time.Second * 1) // 等一秒再继续执行
}
}
第二种,只写判断条件
package main
import (
"fmt"
)
func main() {
fmt.Println("开始")
number := 1
for number < 5 { // 只写了判断条件
fmt.Println("钓鱼要掉刀鱼,刀鱼要到岛上钓")
number = number + 1
}
fmt.Println("结束")
}
package main
import (
"fmt"
)
func main() {
fmt.Println("开始")
flag := true
for flag {
fmt.Println("钓鱼要掉刀鱼,刀鱼要到岛上钓")
flag = false // 设为 false,就会结束,不在循环
}
fmt.Println("结束")
}
第三种,变量&条件
package main
import (
"fmt"
)
func main() {
fmt.Println("开始")
for i := 1; i < 10; { // 变量 i 只在 for 循环内有效,条件为 i<10
fmt.Println("钓鱼要掉刀鱼,刀鱼要到岛上钓")
i = i + 1 // i 会加 1
}
fmt.Println("结束")
}
第四种,变量&条件&变量赋值
package main
import (
"fmt"
)
func main() {
fmt.Println("开始")
for i := 1; i < 10; i = i + 1 { //变量+条件+条件赋值
fmt.Println("钓鱼要掉刀鱼,刀鱼要到岛上钓")
}
// i = i + 1 简化为:i++
for i := 1; i < 10; i++ {
fmt.Println("钓鱼要掉刀鱼,刀鱼要到岛上钓")
}
fmt.Println("结束")
}
上面四种就是 for 循环的四种写法,最常用的是第四种
for range
在 go 中,我们可以通过 for range 来循环,会返回两个值,第一个是索引,第二个是值
package main
import (
"fmt"
)
func main() {
str1 := "hello邹邹"
for _, value := range str1 {
fmt.Println(value)
}
}
结果
104
101
108
108
111
37049
37049
上面代码执行后,会打印一串数字而不是字符。这是由于go语言中的字符串实际上是类型为 byte 的只读切片。或者说一个字符串就是一堆字节。这意味着,当我们将字符存储在字符串中时,实际存储的是这个字符的字节。一个字符串包含了任意个 byte,它并不限定 Unicode,UTF-8 或者任何其他预定义的编码。
我们可以用 string 转换一下
package main
import (
"fmt"
)
func main() {
str1 := "hello邹邹"
for index, value := range str1 {
fmt.Println(index, string(value))
}
}
结果
0 h
1 e
2 l
3 l
4 o
5 邹
8 邹
但上面我们输出的索引是有问题的,所以我们可以转为 rune 的列表,在循环,如下
package main
import (
"fmt"
)
func main() {
str1 := "hello邹邹"
//转成 rune 的列表
for index, value := range []rune(str1) {
fmt.Println(index, string(value))
}
}
结果
0 h
1 e
2 l
3 l
4 o
5 邹
6 邹
continue
在 for 循环中,当循环遇到 continue 关键字时,会停止当前循环,开始下一次循环
案例1:使用循环输出 1 2 3 4 5 6 8 9 10,即:10以内除7以外的整数。
package main
import (
"fmt"
)
func main() {
for i := 1; i <= 10; i++ {
if i == 7 {
continue
}
fmt.Println(i)
}
}
结果
1
2
3
4
5
6
8
9
10
案例2:for循环嵌套 + continue
package main
import (
"fmt"
)
func main() {
for i := 1; i < 3; i++ {
for j := 1; j < 5; j++ {
if j == 3 {
continue
}
fmt.Println(i, j)
}
}
}
结果
1 1
1 2
1 4
2 1
2 2
2 4
break
在 for 循环中时,循环中一旦遇到 break,跳出循环
案例:猜数字,设定一个理想数字比如:66,一直提示让用户输入数字,如果比66大,则显示猜测的结果大了;如果比66小,则显示猜测的结果小了;只有输入等于66,显示猜测结果正确,然后退出循环。
package main
import "fmt"
func main() {
fmt.Print("开始")
data := 66
for {
var userInputNumber int
fmt.Print("请输入数字:")
fmt.Scanln(&userInputNumber)
if userInputNumber > data {
fmt.Println("大了")
} else if userInputNumber < data {
fmt.Println("小了")
} else {
fmt.Println("恭喜你猜对了")
break
}
}
fmt.Print("结束")
}
案例:
package main
import "fmt"
func main() {
for i := 1; i < 3; i++ {
for j := 1; j < 5; j++ {
if j == 3 {
break
}
fmt.Println(i, j)
}
}
}
结果
1 1
1 2
2 1
2 2
给 for 进行打标签
在 go 种,可以对 for 进行打标签,然后通过 break 和 continue 就可以实现多层循环的跳出和终止
package main
import "fmt"
func main() {
f1: // 给 for 打了个标签,f1
for i := 1; i < 3; i++ {
for j := 1; j < 5; j++ {
if j == 3 {
continue f1 // continue 后面加了 f1,则会跳出打了标签的 for 循环
}
fmt.Println(i, j)
}
}
}
结果
1 1
1 2
2 1
2 2
例子
package main
import "fmt"
func main() {
f1: // 给 for 打了个标签,f1
for i := 1; i < 3; i++ {
for j := 1; j < 5; j++ {
if j == 3 {
break f1 // break 后面加了 f1,则会跳出打了标签的 for 循环
}
fmt.Println(i, j)
}
}
}
结果
1 1
1 2
goto 语句
go 语言中的 goto 语句可以无条件的转移到过程中指定的行。
goto 语句通常与条件语句配合使用,可以用来实现条件转移,构成循环,跳出循环体等功能。但是,在结构化程序设计中一般不主张使用 goto 语句,以免造成程序流程的混乱,使理解和调试程序都产生困难
package main
import "fmt"
func main() {
var name string
fmt.Print("请输入姓名:")
fmt.Scanln(&name)
if name == "邹邹" {
// svip
goto SVIP // 直接从 SVIP 处往下执行代码
} else if name == "张三" {
// vip
goto VIP // 直接从 VIP 处往下执行代码
}
fmt.Println("预约...")
VIP: // 给个标记为 VIP
fmt.Println("等号...")
SVIP: // 给个标记为 SVIP
fmt.Println("进入...")
}
我们可以使用 goto 语句来处理错误,例如如下的错误
err := firstCheckError() // 第一个错误
if err != nil{
exitProcess()
return
}
err := secondCheckError() // 第二个错误
if err != nil{
exitProcess()
return
}
fmt.Println("done")
我们可以使用 goto 语句来处理
err := firstCheckError() // 第一个错误
if err != nil{
goto onExit // 跳转到 onExit
}
err := secondCheckError() // 第二个错误
if err != nil{
goto onExit // 跳转到 onExit
}
fmt.Println("done")
onExit: // 跳转到这里执行
exitProcess()