返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

3.3 跳转

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

讨伐已久的 goto ,在运行时源码中不算稀客。

$ grep -r -n "goto" /usr/local/go/src/runtime | wc -l

94

虽然某些设计模式可用来消除 goto 语句,但在性能优先的场合,它能发挥积极作用。

使用前,先定义标签。

  • 标签区分大小写。
  • 未使用的标签会引发编译错误。
  • 不能跳转到其他函数,或内层代码块。
  • 不能导致变量定义跳跃。
func main() {

// start:
// label start defined and not used

	for i := 0; i < 3; i++ {
		if i > 1 {
			goto exit
		}
		println(i)
	}
exit:
	println("exit.")
}
func test() {
	goto test
test:
}

func main() {
	for{
	loop:
	}

	goto test   // label test not defined
	goto loop   // goto loop jumps into block
}
func main() {
	// goto done
	// ~~~~~~~~~ goto done jumps over declaration of v

	v := 0
done:
	println(v)
}

中断

与定点跳转不同,中断结束当前或指定语句块。

  • break :终止 switch/for/select 语句块。
  • continue :仅用于 for,进入下轮循环。
func main() {
	for i := 0; i < 10; i++ {
        
		if i % 2 == 0 {
            continue     // 立即进入下轮循环。(goto next)
		}

		if i > 5 {
			break        // 立即终止整个循环。
		}
        
		println(i)
	}
}

/*

1
3
5

*/

配合标签,在多层嵌套中指定目标。

func main() {
    
outer:
	for x := 0; x < 10; x++ {
        
inner:		
		for y := 0; y < 10; y++ {
			if x % 2 == 0 {
				continue outer
			}

			if y > 3 {
				println()
				break inner
			}
            
			print(x, ":", y, " ")
		}
	}
}

/*

1:0 1:1 1:2 1:3 
3:0 3:1 3:2 3:3 
5:0 5:1 5:2 5:3 
7:0 7:1 7:2 7:3 
9:0 9:1 9:2 9:3

*/
func main() {
    
start:
	switch 1 {
	case 1:
		println(1)
        
		for {
			break start
		}

		println(2)
	}

	println(3)
}

// 1
// 3

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

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

发布评论

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