内容简介:写不过看到Golang中, 不仅保留了在Golang中能使用
写 C/C++
的时候, 基本上都是建议不要使用 goto
的, 因为 goto
运用的不好的话, 会改变程序的运行结构, 会造成程序运行的混乱. 所以很少能看到C++代码中有使用 goto
的.
不过看到Golang中, 不仅保留了 goto
, 而且把它 发扬光大
了.
在Golang中能使用 Label
的有 goto
, break
, continue
. 这篇文章就介绍下Golang中 Label
使用和注意点.
注意点:
-
Label
在continue, break中是可选的
, 但是在goto
中是必须的
-
作用范围: 定义
Label
的函数体内. -
Label
可以声明在函数体的任何位置, 不管Label
声明在调用点
的前面还是后面.
看到国外一篇 文章 写的不错, 加上自己的一些理解, 写了这么一篇文章.
一. goto
下面就以 goto
为例子展示上面三点特点.
1. Label
在 goto
是必须的
package main import ( "fmt" ) func main() { fmt.Println(1) goto End //goto 10: syntax error: unexpected . at end of statement fmt.Println(2) End: fmt.Println(3) }
Output: 1 3
2. Label
可以声明在函数体的任何地方
package main import ( "fmt" ) func main() { End: fmt.Println(1) goto End fmt.Println(2) fmt.Println(3) }
Output 1 1 1 ....
3. Label
的作用范围是在函数体中
package main import ( "fmt" ) func main() { fmt.Println(1) goto End fmt.Println(2) } End: fmt.Println(3)
Output: syntax error: non-declaration statement outside function body
4. Label
在嵌套函数(闭包)是不可用的. 不管是在 闭包里
调用 闭包外
的Label, 还是在 闭包外
调用 闭包里
的Label
package main import ( "fmt" ) func main() { fmt.Println(1) func() { fmt.Println("Nested function") goto End }() End: fmt.Println(2) }
Output 11:label End not defined 13:label End defined and not used
5.不能重复定义 Label
package main import ( "fmt" ) func main() { fmt.Println(1) goto End End fmt.Println(2) { End: fmt.Println(3) } }
Output 14: label End already defined at ./label.go:11
6. Label
和变量名是 不冲突的
, 可以定义一个名为 x
的变量和名为 x
的Label(不过不建议这么用, 这么写会被人骂的); 而且 Label
是区分大小写的.
package main import ( "fmt" ) func main() { x := 1 fmt.Println(x) goto x x: fmt.Println(2) }
Output: 1 2
7.变量的声明必须在 goto
之前.
package main import ( "fmt" ) func main() { goto End j := 2 fmt.Println(j) End: fmt.Println(1) }
Output goto End jumps over declaration of i at ./label.go:9
这是为什么呢? 因为任何变量的声明都不能被跳过.
需要改成下面的形式
package main import ( "fmt" ) func main() { j := 2 goto End fmt.Println(j) End: fmt.Println(2) }
二. break(不带label)
break
一般用来跳出 最近
一层的 switch
和 for
, 注意不能用在 select
上
1.单层循环
package main import ( "fmt" ) func main() { for i := 0; i < 10; i++ { fmt.Println(i) if i == 3 { break } } }
Output 0 1 2 3
2.双层循环
package main import ( "fmt" ) func main() { for i := 0; i < 3; i++ { for j := 0; j < 5; j++ { fmt.Println("i:", i, ",j:", j) if j == 2 { break } } } }
Output i: 0 ,j: 0 i: 0 ,j: 1 i: 0 ,j: 2 i: 1 ,j: 0 i: 1 ,j: 1 i: 1 ,j: 2 i: 2 ,j: 0 i: 2 ,j: 1 i: 2 ,j: 2
从这个例子可以看出 break
只能跳出最近 for
3.对于 c/c++
来说, switch/case
一般都是配合 break
来使用的.但是在 golang
中 switch/case
不需要 break
就能够实现和 c/c++
一样的效果.
package main import ( "fmt" ) func main() { i := 1 switch { case i == 0: fmt.Println(i) case i == 1: fmt.Println(i) //break 这里可以使用`break`,但是么有啥效果, 不如不写 case i == 2: fmt.Println(i) } }
Output
1
如果想继续往下执行, 需要使用 fallthrough
package main import ( "fmt" ) func main() { i := 1 switch { case i == 0: fmt.Println(0) case i == 1: fmt.Println(1) fallthrough case i == 2: fmt.Println(2) } }
Output: 1 2
4. break
在函数里是不起作用的, 不能传递出来.
package main func f() { break } func main() { for i := 0; i < 10; i++ { f() } }
output 4: break is not in a loop
三.break(Label)
break
携带 label
可以用在 for
, switch
, select
上.
1.对于 for
/ select
/ switch
, Label
必须紧挨着他们.
FirstLoop: for i := 0; i < 10; i++ { //invalid break label FirstLoop } for i := 0; i < 10; i++ { break FirstLoop }
必须改成这样
func main() { for i := 0; i < 10; i++ { fmt.Println(i) } FirstLoop: for i := 0; i < 10; i++ { break FirstLoop } }
对于 select
和 switch
也是一样.
func main() { FirstLoop: j := 1 switch j { case 0: fmt.Println(0) case 1: fmt.Println(1) break FirstLoop // invalid break label FirstLoop } }
2.一般来说 break
只能跳出最近一层的 for
, switch
, 但是 break Label
就可以直接跳出最外面的循环.
func main() { OuterLoop: for i := 0; i < 10; i++ { for j := 0; j < 10; j++ { fmt.Printf("i=%v, j=%v\n", i, j) break OuterLoop } } }
Output i=0, j=0
SwitchStatement: switch 1 { case 1: fmt.Println(1) for i := 0; i < 10; i++ { break SwitchStatement } fmt.Println(2) } fmt.Println(3)
Output 1 3
四. continue
continue
用法基本上和 break
差不多.
1.正常的用法, 调过当前循环, 继续执行下一次
package main import ( "fmt" ) func main() { for i := 0; i < 5; i++ { if i == 3 { continue } fmt.Println(i) } }
Output 0 1 2 4
2. continue
和 label
一起使用(其实和不使用Label效果一样)
func main() { Test: for i := 0; i < 5; i++ { if i == 3 { continue Test } fmt.Println(i) } }
Output 0 1 2 4
3. continue
和双层循环一起使用
OuterLoop: for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { fmt.Printf(“i=%v, j=%v\n”, i, j) continue OuterLoop } }
Output i=0, j=0 i=1, j=0 i=2, j=0
参考资料:
以上所述就是小编给大家介绍的《Golang Label使用方法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- [译] 通过实现 25 个数组方法来理解及高效使用数组方法
- AWK简单使用方法
- python 内置函数使用方法
- 栈和帧指针使用方法
- c# – 为什么委托在静态方法中使用时不能引用非静态方法?
- MyEclipse中的MySQL使用方法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
MD5 加密
MD5 加密工具
html转js在线工具
html转js在线工具