300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Go 学习笔记(9)— 循环(for for range访问数组 切片 字符串和通道 goto continue break)

Go 学习笔记(9)— 循环(for for range访问数组 切片 字符串和通道 goto continue break)

时间:2020-09-02 06:58:25

相关推荐

Go 学习笔记(9)— 循环(for for range访问数组 切片 字符串和通道 goto continue break)

1. for 循环格式

Go语言仅支持一种循环语句即for循环,它有 3 种形式,只有其中的一种使用分号。

和 C 语言的 for 一样

for init; condition; post {}

init: 一般为赋值表达式,给控制变量赋初值,初始语句是在第一次循环前执行的语句,一般使用初始语句执行变量初始化,如果变量在此处被声明,其作用域将被局限在这个for的范围内。

condition: 关系表达式或逻辑表达式,循环控制条件,每次循环开始前都会计算条件表达式,如果表达式为true,则循环继续,否则结束循环,条件表达式可以被忽略,忽略条件表达式后默认形成无限循环。

post: 一般为赋值表达式,给控制变量增量或减量;

可以看到比较大的一个不同在于for后面的条件表达式不需要用圆括号()括起来。左花括号{必须与for处于同一行。

Go语言中的for循环与C语言一样,都允许在循环条件中定义和初始化变量,唯一的区别是,Go语言不支持以逗号为间隔的多个赋值语句,必须使用平行赋值的方式来初始化多个变量。

示例-1:

var i intfor ; ; i++ {if i > 10 {break}}

Cwhile一样

for condition {}

示例-2

var i intfor i <= 10 {i++}

Cfor(;;)一样,无限循环

for {}

示例-3

var i intfor {if i > 10 {break}i++}

2. for 循环示例

package mainimport "fmt"func main() {var b int = 15var a intnumbers := [6]int{1, 2, 3, 5} /* for 循环 */for a := 0; a < 10; a++ {// 左花括号{必须与 for 处于同一行fmt.Printf("a 的值为: %d\n", a)}for a < b {a++fmt.Printf("a 的值为: %d\n", a)}for i, x:= range numbers {fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)} }

3. 嵌套 for 循环

package mainimport "fmt"func main() {/* 定义局部变量 */var i, j intfor i=2; i < 100; i++ {for j=2; j <= (i/j); j++ {if(i%j==0) {break; // 如果发现因子,则不是素数}}if(j > (i/j)) {fmt.Printf("%d 是素数\n", i);}} }

4. for 循环应用

Go语言中range关键字用于for循环中迭代数组 (array)、切片(slice)、通道(channel)或集合 (map) 的元素。通过for range遍历的返回值有一定的规律:

数组、切片、字符串返回索引和值。map返回键和值。通道(channel)只返回通道内的值。

4.1 访问数组

for index , value :=range arry{}for index := range arry{}for _, value :=range arry{}

在上面的例子中将 key 变成了下划线_,这里的下划线就是匿名变量。

可以理解为一种占位符匿名变量本身不会进行空间分配,也不会占用一个变量的名字在for range可以对key使用匿名变量,也可以对value使用匿名变量

package mainimport "fmt"func main() {array := [3]int{10, 20, 30}for i, v := range array {fmt.Printf("index is %v, value is %v\n", i, v)}for _, v := range array {fmt.Printf("value is %v\n", v)}for i := range array {fmt.Printf("index is %v\n", i)}}

输出:

index is 0, value is 10index is 1, value is 20index is 2, value is 30value is 10value is 20value is 30index is 0index is 1index is 2

4.2 访问切片

for index, value :=range slice{}for index := range slice{}for _, value :=range slice{}

代码演示和数组类似,只需要做如下改动:

array := [3]int{10, 20, 30} // 数组array := []int{10, 20, 30}// 切片

4.3 访问字典

对于map类型来说,for range 遍历时,keyvalue分别代表map的索引键key和索引对应的值,一般被称为map的键值对,因为它们是一对一对出现的。

for key , value := range map{}for key := range map {}

4.4 访问字符串

range也可以用来枚举Unicode字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。

for index, value := range stringfor index := range string

示例:

package mainimport "fmt"func main() {s := "hello"for i := range s {fmt.Printf("value is %v\n", s[i])}}

4.5 访问通道

for range可以遍历通道(channel),但是通道在遍历时,只输出一个值,即管道内的类型对应的数据。

for value :=range channel{}

代码示例:

c := make(chan int)go func() {c <- 1c <- 2c <- 3close(c)}()for v := range c {fmt.Println(v)}

4. 循环控制语句

4.1 goto

goto语句用于函数的内部的跳转,需要配合标签一起使用, 具体的格式如下:

goto Lable

goto Lable的语义是跳转到标签名后的语句处执行,goto语句有以下几个特点:

goto语句只能在函数内跳转;goto语句不能跳过内部变量声明语句,这些变量在goto语句的标签语句处又是可见的;

goto L // BAD ,跳过v := 3 这条语句是不允许的v := 3L :

goto语句只能跳到同级作用域或者上层作用域内,不能跳到内部作用域内;

if n%2 == 1 {goto LL}for n > 0 {f()n-- LL:f()n--}

代码示例:

package mainimport "fmt"func main() {for x := 0; x < 10; x++ {for y := 0; y < 10; y++ {if y == 2 {// 跳转到标签goto breakHere}}}// 手动返回, 避免执行进入标签return// 标签breakHere:fmt.Println("done")}

4.2 continue

跳过当前循环的剩余语句,仅能用于continue语句,然后继续进行下一轮循环,有两种格式:

单独使用,用于跳出continue当前所在的for循环的本次迭代;

和标签一起使用,用于跳出标签所标识的for语句的本次选代,但标签和continue必须在同一个函数内。

例如:

package mainimport "fmt"func main() {OuterLoop:for i := 0; i < 2; i++ {for j := 0; j < 5; j++ {switch j {case 2:fmt.Println(i, j)continue OuterLoop}}}}

4.3 break

break用于函数内跳出forswitchselect语句的执行,有两种使用格式:

单独使用,用于跳出break当前所在的forswitchselect语句的执行;

和标签一起使用,用于跳出标签所标识的forswitchselect语句的执行,可用于跳出多重循环,但标签和break必须在同一个函数内。

例如:

package mainimport "fmt"func main() {Ll:for i := 0; ; i++ {for j := 0; ; j++ {if i >= 5 {// 跳到 Ll 标签所在的 for 循环 i++ 处执行fmt.Println(i)break Ll//the following is not executed}if j > 10 {fmt.Println(j)// 默认仅跳到离 break 最近的内层循环 j++ 处执行break}}}}

不带labelbreak语句中断执行并跳出的,是同一函数内break语句所在的最内层的forswitchselect

func main() {var sl = []int{5, 19, 6, 3, 8, 12}var firstEven int = -1// find first even number of the interger sliceloop:for i := 0; i < len(sl); i++ {switch sl[i] % 2 {case 0:firstEven = sl[i]break loopcase 1:// do nothing}}println(firstEven) // 6}

我们定义了一个 label:loop,这个label附在for循环的外面,指代for循环的执行。当代码执行到break loop时,程序将停止label loop所指代的for循环的执行。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。