【Go】Go 语言的循环语句: for、break、continue、goto、range

导读:本篇文章讲解 【Go】Go 语言的循环语句: for、break、continue、goto、range,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com


1. 循环语句

Go语言中只有 for 循环。
Go中的 for 循环可以实现其它语言中的 for、while循环和遍历迭代。


2. for 循环

for 循环是一个循环控制结构,可以执行指定次数的循环。

(1) 语法

Go 语言的 For 循环有 4 种形式,只有其中的一种使用分号。

和 C 语言的 for 一样:

for init; condition; post { }

和 C 的 while 一样:

for condition { }

和 C 的 for( ; ; ) 一样:

//无限循环  相当于 for true {}
for { }

for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:
for range很重要,将在 5 中详细讲解。

for key, value := range oldMap {
    newMap[key] = value
}

init: 一般为赋值表达式,给控制变量赋初值;
condition: 关系表达式或逻辑表达式,循环控制条件;
post: 一般为赋值表达式,给控制变量增量或减量。

(2) for语句执行过程

1、先对表达式 init 赋初值;

2、判别赋值表达式 init 是否满足给定条件 condition,若其值为真,满足循环条件,则执行循环体内语句,然后执行 post,进入第二次循环,判别 condition;若 condition 的值为假,不满足条件,就终止for循环。


3. 循环嵌套

Go 语言允许用户在循环内使用循环:

for [condition |  ( init; condition; increment ) | Range]
{
   for [condition |  ( init; condition; increment ) | Range]
   {
      statement(s);
   }
   statement(s);
}

实例:使用循环嵌套来输出 2 到 100 间的素数

package main

import "fmt"

func main() {
	/* 定义局部变量 */
	var i, j int

	for 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)
		}
	}
}

输出结果:

2  是素数
3  是素数
5  是素数
7  是素数
11  是素数
13  是素数
17  是素数
19  是素数
23  是素数
29  是素数
31  是素数
37  是素数
41  是素数
43  是素数
47  是素数
53  是素数
59  是素数
61  是素数
67  是素数
71  是素数
73  是素数
79  是素数
83  是素数
89  是素数
97  是素数

4. 循环控制

循环控制语句可以控制循环体内语句的执行过程。

GO 语言支持以下几种循环控制语句:
在这里插入图片描述

  1. 这三个语句都可以配合标签(label)使用
  2. 标签名区分大小写,定义以后若不使用会造成编译错误
  3. continue、break配合标签(label)可用于多层循环跳出
  4. goto是调整执行位置,与continue、break配合标签(label)的结果并不相同

(1) break

break 语句用途:

  1. 用于循环语句中跳出循环,并开始执行循环之后的语句。
  2. break 在 switch(开关语句)中在执行一条 case 后跳出语句的作用。
  3. 在多重循环中,可以用标号 label 标出想 break 的循环。

多重循环时,使用标记和不使用标记的区别:

package main

import "fmt"

func main() {

	// 不使用标记
	fmt.Println("---- break ----")
	for i := 1; i <= 3; i++ {
		fmt.Printf("i: %d\n", i)
		for i2 := 11; i2 <= 13; i2++ {
			fmt.Printf("i2: %d\n", i2)
			break
		}
	}

	// 使用标记
	fmt.Println("---- break label ----")
re:   //re是一个标记
	for i := 1; i <= 3; i++ {
		fmt.Printf("i: %d\n", i)
		for i2 := 11; i2 <= 13; i2++ {
			fmt.Printf("i2: %d\n", i2)
			break re
		}
	}
}

(2) continue

continue 语句用途:

  1. continue 语句 有点像 break 语句。但是 continue 不是跳出循环,而是跳过当前循环执行下一次循环语句。
  2. for 循环中,执行 continue 语句会触发 for 增量语句 increment 的执行。
  3. 在多重循环中,可以用标号 label 标出想 continue 的循环。

(3) goto

goto语句用途:

  1. Go 语言的 goto 语句可以无条件地转移到过程中指定的行。
  2. goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。

但是,在结构化程序设计中一般 不主张 使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。

goto 语法格式如下:

goto label;
..
.
label: statement;

5. 循环语句 range (for range 实现迭代器)

(1)语法

Golang range 类似迭代器操作,返回 (索引, 值) 或 (键, 值)。

for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:

for key, value := range oldMap {
    newMap[key] = value
}

在这里插入图片描述

(2)选择性接收值

可只设置一个接收器忽略 range 返回的第二个值,或使用 “_” 这个特殊变量忽略第一个返回值。没有接收器就是忽略全部返回值。

package main

func main() {
	s := "abc"
	// 忽略 2nd value,支持 string/array/slice/map。
	for i := range s {
		println(s[i])
	}
	// 忽略 index。
	for _, c := range s {
		println(c)
	}
	// 忽略全部返回值,仅迭代。
	for range s {

	}

	m := map[string]int{"a": 1, "b": 2}
	// 返回 (key, value)。
	for k, v := range m {
		println(k, v)
	}
}

输出结果:

97
98
99
97
98
99
a 1
b 2

(3)range 会复制值对象

package main

import "fmt"

func main() {
	a := [3]int{0, 1, 2}

	for i, v := range a { // range复制数组a。index、value 都是从复制品中取出。

		if i == 0 { // 我们先修改原数组。
			a[1], a[2] = 999, 999
			fmt.Println(a) // 确认修改有效,输出 [0, 999, 999]。
		}

		a[i] = v + 100 // range 使用复制品中取出的 value 修改原数组。

	}

	fmt.Println(a) 
}

输出结果:

[0 999 999]
[100 101 102]  //而不是[100 1099 1099]

建议改用引用类型,其底层数据不会被复制。

package main

func main() {
	s := []int{1, 2, 3, 4, 5}

	for i, v := range s { // s是切片,一种引用类型。range复制slice的struct:{ pointer, len, cap }。

		if i == 0 {
			s = s[:3]  // 对 slice 的修改,不会影响 range。
			s[2] = 100 // 对底层数据的修改。
		}
		println(i, v)
	}
}

输出结果:

0 1
1 2
2 100
3 4
4 5

另外两种引用类型 map、channel 是指针包装,而不像 slice 是 struct。

(4)for 和 for range 的区别

它们的区别主要是使用场景不同。

for可以:

  • 遍历array和slice

  • 遍历key为整型递增的map

  • 遍历string

for range可以完成所有for可以做的事情,却能做到for不能做的,包括

  • 遍历key为string类型的map并同时获取key和value

  • 遍历channel


参考链接

  1. Go 语言循环语句

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/119044.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!