返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

3.2 循环

发布于 2024-10-12 19:15:47 字数 2243 浏览 0 评论 0 收藏 0

for 一种循环语句,常用方式都能支持。

func main() {
	
	for i := 0; i < 3; i++ {
	}

    x := 0
	for x < 10 {
		x++
	}

	for {
		break
	}

}
  • 初始化语句仅执行一次。
  • 条件表达式中的函数被多次调用,或被内联优化。
func count() int {
	print("count.")
	return 3
}

func main() {

	// 初始化语句仅执行一次。
	for i, c := 0, count(); i < c; i++ {
		println("a", i)
	}
    
	c := 0

	// 条件表达式,多次调用。
	for c < count() {
		println("b", c)
		c++
	}
}

所定义变量,在整个循环周期内重复使用。

func main() {
	for i := 0; i < 3; i++ {
		println(&i)
	}
}

/*

0xc000032768
0xc000032768
0xc000032768

*/

迭代

for...range 迭代数组、切片、字典等。

  type              1st value      2nd value
-----------------+--------------+--------------+-----------------
  string            index          s[index]       unicode, rune
  array, slice      index          v[index]
  map               key            value
  channel           element
  
func main() {
	data := []int{10, 11, 12}

	for i, s := range data {
		println(i, s)
	}
}

/*

0 10
1 11
2 12

*/

允许返回单值,或用 _ 忽略。

func main() {
	data := []int{10, 11, 12}

	for i := range data {
		println(i)
	}

	for _, v := range data {
		println(v)
	}

	for range data {
		println("a")
	}
}

定义的局部变量会重复使用。

func main() {
	data := []int{ 1, 2, 3 }
    
	for i, s := range data {
		println(&i, &s)
	}
}

/*

0xc000032748 0xc000032740
0xc000032748 0xc000032740
0xc000032748 0xc000032740

*/

注意, range 会复制目标数据。受直接影响的是数组,改用切片或指针。

func main() {
	data := [...]int{1, 2, 3}

	for i, x := range data {
		if i == 0 {
			data[0] += 100
			data[1] += 200
			data[2] += 300
		}

		println(x, data[i])
	}
}

/*

1 101
2 202
3 303

$ go tool objdump -S -s "main\.main" ./test

func main() {

	data := [...]int{1, 2, 3}

	MOVQ $0x1, 0x20(SP)	
	MOVQ $0x2, 0x28(SP)	
	MOVQ $0x3, 0x30(SP)	

	for i, x := range data {
		
	MOVQ $0x1, 0x38(SP)	
	MOVQ $0x2, 0x40(SP)	
	MOVQ $0x3, 0x48(SP)	

*/

如目标表达式是函数调用,仅执行一次。

//go:noinline
func data() []int {
	println("data")
	return []int{10, 20, 30}
}

func main() {
	for _, x := range data() {
		println(x)
	}
}

/*

data
10
20
30

*/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文