for结构
for 结构可以使用于执行某些语句,for结构比其他语言更为灵活。
for结构可以演示再简单的计数器的迭代,基本形式为:
♾️ go 代码:for 初始语句;条件语句;修饰语句{}
eg:
♾️ go 代码:package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
fmt.Printf("This is the %d iteration\n", i)
}
}
运行结果:
花括号括起来的代码会被重复执行已知的次数,该次数是根据计数器(以上为i)决定的,会只执行一次初始化语句i:= 0;
这比在循环之前声明更为间短。紧接着的是条件语句 i < 5;
在每次循环开始前否会进行判断,一旦判断结果为false,则退出循环体。最后一部分修饰语句 i ++
一般用于增加或减少计数器。
这三部分组成的循环的头部,之间使用分号 “;” 相隔,但并不需要括号“()”将他们括起来。
左边的花括号 “{” 必须和for语句在同一行,计数器的生命周期在遇到右花括号“}”时便会终止一般都会用较为短的名称命名计数器。
注意不能再循环体内修改计数器,但是可以在循环中同时使用多个计数器:
eg:
♾️ go 代码:for i, j := 0, N; i < j; i, j = i+1, j-1 {}
两个for循环可以嵌套起来:
♾️ go 代码:for i:=0; i<5; i++{
for j:=; j<10; j++ {
Println(j)
}
}
for 循环迭代一个Unicode编码的字符串:
eg:
package main
import "fmt"
func main() {
str := "Go is a beautiful language!"
fmt.Printf("The length of str is: %d\n", len(str))
for ix :=0; ix < len(str); ix++ {
fmt.Printf("Character on position %d is: %c \n", ix, str[ix])
}
str2 := "日本語"
fmt.Printf("The length of str2 is: %d\n", len(str2))
for ix :=0; ix < len(str2); ix++ {
fmt.Printf("Character on position %d is: %c \n", ix, str2[ix])
}
}
运行结果:
基于条件判断的迭代
for结构的第二种形式是没有头部的条件判断迭代(类似于其他语言中的while循环),基本形式为:for
条件语句{}。
也可以认为是没有初始化语句和修饰语句的for
结构,因此 “ ;;” 便是多余的了。
案例:
♾️ go 代码:package main
import "fmt"
func main() {
var i nt = 5
for i >= 0 {
i = i - 1
fmt.printf("The variable i is now: %d\n", i )
}
}
运行结果:
无限循环
条件语句是可以被省略的 ,例如 i:=0;
i++
或for{}
、for;;☑️
(;;会在使用gofmt时被移除: 这些循环的本质就是无限循环,最后一个形式也可以被改写成for trun{}
但一般情况下会长慧姐些 for {}。
如果for头部没有条件语句,那么就会认为条件永远为true,因此循环体内必须有相关的条件判断来决定某个时候退出循环。若想要直接退出循环,可以使用break,知识退出当前的训话,return 语句会提前对函数进行但会,不会执行后续的代码。
无限循环的经典应用就是服务器,用于不但等待和接受新的请求。
结构案例:
for t, err = p.Token(); err == nil; t, err = p.Token() {
....
}
for-range结构
这是Go特有的一种迭代,在许多情况下都可使用,可以迭代任何一个集合(包括数组和map)。一般形式为for ix, val := range coll {}
当然也可以用于迭字符串
eg:
for pos, char := range str {
....
}
每个rune字符和索引在foe-range循环中是一一对应的。能够自动根据UTF-8规则识别Unicode编码的字节。
♾️ go 代码:package main
import "fmt"
func main() {
str := "Go is a beautiful language!"
fmt.Printf("The length of str is: %d\n", len(str))
for pos, char := range str {
fmt.Printf("Character on position %d is: %c \n", pos, char)
}
fmt.Println()
str2 := "Chinese: 日本語"
fmt.Printf("The length of str2 is: %d\n", len(str2))
for pos, char := range str2 {
fmt.Printf("character %c starts at byte position %d\n", char, pos)
}
fmt.Println()
fmt.Println("index int(rune) rune char bytes")
for index, rune := range str2 {
fmt.Printf("%-2d %d %U '%c' % X\n", index, rune, rune, rune, []byte(string(rune)))
}
}
运行结果:
{dotted startColor="#ff6c6c" endColor="#1989fa"/}
Braek与continue
可以用break语句重写for语句条件判断的迭代
♾️ go 代码:for {
i = i - 1
fmt.Printf("The variable i is now: %d\n", i)
if i < 0 {
break
}
}
运行结果:
因此每次迭代都会对条件进行检查(i < 0),以此判断是否需要停止循环。如果退出条件满足,则使用 break 语句退出循环。一个 break 的作用范围为该语句出现后的最内部的结构,它可以被用于任何形式的 for 循环(计数器、条件判断等)。但在 switch 或 select 语句中,break 语句的作用结果是跳过整个代码块,执行后续的代码。
break值退出最内层的循环:
package main
func main() {
for i:=0; i<3; i++ {
for j:=0; j<10; j++ {
if j>5 {
break
}
print(j)
}
print(" ")
}
}
运行结果:
关键字 continue 忽略剩余的循环体而直接进入下一次循环的过程,但不是无条件执行下一次循环,执行之前依旧需要满足循环的判断条件。
案例:
♾️ go 代码:package main
func main() {
for i := 0; i < 10; i++ {
if i == 5 {
continue
}
print(i)
print(" ")
}
}
运行结果: