内容简介:写不过看到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使用方法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Inside Larry's and Sergey's Brain
Richard Brandt / Portfolio / 17 Sep 2009 / USD 24.95
You’ve used their products. You’ve heard about their skyrocketing wealth and “don’t be evil” business motto. But how much do you really know about Google’s founders, Larry Page and Sergey Brin? Inside......一起来看看 《Inside Larry's and Sergey's Brain》 这本书的介绍吧!