go学习笔记(19)goto

IMG_6508.jpg

go语言中是有goto语句的,最好不要使用goto语句,能用goto的地方都可以用其他语句来代替,我们在平常编程过程中大概永远都不会用到goto语句。

goto语句过于强大,可以在程序各处来回横跳,胡乱使用的话会导致代码无法理解。

在c/c++中我们为了跳出嵌套循环会使用goto,而go语言中可以用break实现相同的操作。

go语言之所以保留了goto语句,是因为在一些特殊情况下goto可以大大简化代码。

go语言的goto有一些语法上的限制。go禁止用goto跳过变量的声明,禁止直接跳到代码块内部。

这个限制很好理解,跳过变量声明那后面用到这个变量肯定程序就崩了。跳到代码块内部会打乱代码执行顺序加大程序理解的难度,大大增加bug出现率。

比如这段代码:
f7c97baa9aa7a7e42cc121e936194835.png

在编译时会报这两个错误:

1
2
goto skipy jumps over declaration of y at ./main.go:448:4
goto innerblock jumps into block starting at ./main.go:456:11

goto语句适合用在当我们想依据条件退出循环后,选择性地执行一些语句,同时又能让收尾的语句不受影响的情况:

一个模拟面试的例子:

1
2
3
4
5
6
7
8
9
10
11
score := 100
for i := 0; i < 4; i++ {
score -= rand.Intn(11)
if score < 80 {
goto normal
}
}

fmt.Println("恭喜您通过面试!")
normal:
fmt.Println("面试已结束")

输出:

1
2
3
4
5
6
// 四轮面试结束后总分大于等于80分
恭喜您通过面试!
面试已结束

// 几轮面试后总分小于80分
面试已结束

这个例子只是为了举例而硬凑的。上面的例子如果不用goto来写且限制必须在循环结束后再输出结果,就需要在循环结束后用if来判断一下要不要打印“恭喜您通过面试!”这句话。借助goto可以去掉这个if,不再需要辅助变量来判断循环是否正常退出。

goto语句在使用时一定要慎之又慎,能不用尽量不用,当其他的手段都用尽后代码还是冗长难以维护,这时可以试试能不能通过goto来简化。

江达小记