Go语言的LABLE标签与goto语句
标签与 goto
这些控制结构均可搭配标签(label)形式的标识符进行操作;其中,在某些情况下,则会在某些特定条件下执行特定的操作行为;例如,在某些情况下,则会在某些特定条件下执行特定的操作行为;例如
示例 5.13 for6.go:
为了增强可读性,在选择标签名称时通常推荐使用全部大写字母作为其名称。
package main
import "fmt"
func main() {
LABEL1:
for i := 0; i <= 5; i++ {
for j := 0; j <= 5; j++ {
if j == 4 {
continue LABEL1
}
fmt.Printf("i is: %d, and j is: %d\n", i, j)
}
}
}
在本例中,在程序运行过程中会遇到一个continue关键字,并将其引导至LABEL1标签处。
当处理到j等于4或5时会出现没有输出的情况:这是因为标签指向外部循环结构,在这种情况下变量i会被自动更新到下一个外层循环的起始位置,并且j会被重新初始化为其初始值。若将continue语句改为break语句,则该操作将导致仅退出内层循环而不是外层循环。此外还可采用goto语句与标签配合的方式来模拟多层循环结构
示例 5.14 goto.go:
package main
func main() {
i:=0
HERE:
print(i)
i++
if i==5 {
return
}
goto HERE
}
上面的代码会输出 01234。
反向的 goto 很快会导致意大利面条式的代码出现;因此不应采取这种做法而应寻找更优的替代方案。
特别强调,在编程中应避免使用标签和 goto 语句;这些会导致容易导致非常糟糕的程序设计,并总是存在更为易懂且功能完善的替代方案来实现相同的功能需求。
作为一项建议,在第 15.1 章的 simple_tcp_server.go 中可以找到一个示例:该示例表明,在遇到读取错误时,通过使用 goto 语句跳出无限读取循环,并关闭相应的客户端链接。
定义但未使用标签会导致编译错误:label … defined and not used。
当采用 goto 语句时应遵循以下原则:所有标签必须位于 goto 后面,并且这些标签的位置应按照代码执行顺序排列。特别提示:在代码中不允许在 tag 和 corresponding go-to statement之间插入新的 variable 宣告。这将导致编译错误。
示例 5.15 goto2.go:
// compile error goto2.go:8: goto TARGET jumps over declaration of b at goto2.go:8
package main
import "fmt"
func main() {
a := 1
goto TARGET // compile error
b := 9
TARGET:
b += a
fmt.Printf("a is %v *** b is %v", a, b)
}
