首页 技术 正文
技术 2022年11月18日
0 收藏 861 点赞 2,850 浏览 3443 个字

在Golang中能使用Label的有gotobreakcontinue.,这篇文章就介绍下Golang中Label使用和注意点.

注意点:

  1. Label在continue, break中是可选的, 但是在goto中是必须的
  2. 作用范围: 定义Label的函数体内.
  3. Label可以声明在函数体的任何位置, 不管Label声明在调用点的前面还是后面.

一. goto

下面就以goto为例子展示上面三点特点.

1.Labelgoto是必须的

package mainimport (
"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 mainimport (
"fmt"
)func main() {
End:
fmt.Println(1)
goto End
fmt.Println(2)
fmt.Println(3)
}

输出

Output
1
1
1
....

3.Label的作用范围是在函数体中

package mainimport (
"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 mainimport (
"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 mainimport (
"fmt"
)func main() {
fmt.Println(1)
goto EndEnd
fmt.Println(2)
{
End:
fmt.Println(3)
}
}

输出

Output
14: label End already defined at ./label.go:11

6.Label和变量名是不冲突的, 可以定义一个名为x的变量和名为x的Label(不过不建议这么用, 这么写会被人骂的); 而且Label是区分大小写的.

package mainimport (
"fmt"
)func main() {
x := 1
fmt.Println(x)
goto x
x:
fmt.Println(2)
}

输出

Output:
1
2

7.变量的声明必须在goto之前.

package mainimport (
"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 mainimport (
"fmt"
)func main() {
j := 2
goto End
fmt.Println(j)
End:
fmt.Println(2)
}

二. break(不带label)

break一般用来跳出最近一层的switchfor, 注意不能用在select

1.单层循环

package mainimport (
"fmt"
)func main() {
for i := 0; i < 10; i++ {
fmt.Println(i)
if i == 3 {
break
}
}
}

输出

Output
0
1
2
3

2.双层循环

package mainimport (
"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来使用的.但是在golangswitch/case不需要break就能够实现和c/c++一样的效果.

package mainimport (
"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 mainimport (
"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 mainfunc 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
}
}

对于selectswitch也是一样.

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只能跳出最近一层的forswitch, 但是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 mainimport (
"fmt"
)func main() {
for i := 0; i < 5; i++ {
if i == 3 {
continue
}
fmt.Println(i)
}
}

输出

Output
0
1
2
4

2.continuelabel一起使用(其实和不使用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
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,085
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,560
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,409
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,182
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,819
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,902