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("进入...")
}

go--for 循环、continue、break、goto_i++

go--for 循环、continue、break、goto_字符串_02

go--for 循环、continue、break、goto_死循环_03

我们可以使用 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()