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

注意点:

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

一. goto

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

1.Labelgoto是必须的

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一般用来跳出最近一层的switchfor, 注意不能用在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来使用的.但是在golangswitch/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
}
}

对于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 main

import (
"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

Golang中Label的用法的更多相关文章

  1. golang中type常用用法

    golang中,type是非常重要的关键字,一般常见用法就是定义结构,接口等,但是type还有很多其它的用法,在学习中遇到了以下几种,这点简单总结记录下 定义结构 type Person struct ...

  2. golang 中strconv包用法

    链接:https://studygolang.com/articles/5003 http://www.cnblogs.com/golove/p/3262925.html

  3. Golang中的RegExp正则表达式用法指南

    ------------------------------------------------------------ Golang中的正则表达式 ------------------------- ...

  4. 基础知识 - Golang 中的正则表达式

    ------------------------------------------------------------ Golang中的正则表达式 ------------------------- ...

  5. golang中的reflect包用法

    最近在写一个自动生成api文档的功能,用到了reflect包来给结构体赋值,给空数组新增一个元素,这样只要定义一个input结构体和一个output的结构体,并填写一些相关tag信息,就能使用程序来生 ...

  6. java中this的用法?

    2008-07-28 08:10cztx5479 | 分类:JAVA相关 | 浏览4533次 java中this的用法? import java.awt.*; import java.awt.even ...

  7. JAVA语言中冒号的用法

    近来由于本人要介入android平台的开发,所以就买了本JAVA语言的书学习.学习一段时间来,我的感觉是谭浩强就是厉害,编写的<C编程语言>系列丛书不愧是经典.书中对C语言的介绍既系统又全 ...

  8. golang 的 http cookie 用法

    golang的http cookie用法 在服务端程序开发的过程中,cookie经常被用于验证用户登录.golang 的 net/http 包中自带 http cookie的定义,下面就来讲一下coo ...

  9. Golang 中的坑 一

    Golang 中的坑 短变量声明  Short variable declarations 考虑如下代码: package main import ( "errors" " ...

随机推荐

  1. Go modules基础精进,六大核心概念全解析(上)

    点击一键订阅<云荐大咖>专栏,获取官方推荐精品内容,学技术不迷路! Go 语言做开发时,路径是如何定义的?Go Mudules又为此带来了哪些改变?本文将会全面介绍Go modules六大 ...

  2. 了解C#的Expression

    我们书接上文,我们在了解LINQ下面有说到在本地查询IEnumerbale主要是用委托来作为传参,而解析型查询 IQueryable则用Expression来作为传参: public static I ...

  3. Mysql-5.6 二进制多实例部署

    目录 一.简介 二.环境声明 三.程序部署 一.简介 MySQL多实例就是在一台机器上开启多个不同的服务端口(如:3306,3307),运行多个MySQL服务进程,通过不同的socket监听不同的服务 ...

  4. Gitlab-CICD实践篇

    一.背景 随着公司项目使用gitlab越来越多,业务发布的次数越来越频繁,对于发布效率提出了更高的要求.从2012开始,Gitlab官方开始集成了Continuous Integration (CI) ...

  5. Tableau如何绘制堆叠柱状图

    一.将类别,子类别拖拽至列上 二.将度量值拖拽至行上 三.将度量名称拖拽至筛选器上,右键度量名称,编辑筛选器,选择销售额 四.将事先准备的目标销售额拖拽至度量值 五.将度量名称拖拽至标记,分别以颜色和 ...

  6. java 理论基础 类的初始化(加载、连接(验证、准备、解析)、初始化)

    一个进程就有一个JVM,每个进程之间资源独立 当调用java命令来启动某个Java程序的时候,该命令创建一个独立的进程来运行我们的Java程序.而这个独立的进程里面就包含一个Java虚拟机.不管该程序 ...

  7. Python第三周 函数详解

    def 函数名(): """注释说明"""" 执行逻辑体 return 返回值 定义不带参数的函数 带参数的函数 默认参数 这个是 ...

  8. IPtables 之“四表五链”

    目录 架构图 IP tables 简介 包过滤防火墙 Iptables如何过滤 "四表" "五链" Iptables流程 架构图 公司架构模式(酒店迎宾比喻) ...

  9. Linux(centos7)设置docker服务开机自启动以及容器自启动

    docker服务开机自启动 systemctl enable docker 设置容器自启动 可以在运行的时候通过设置--restart 参数 docker run --restart always - ...

  10. Spring实现自定义注解并且配置拦截器进行拦截

    有时候我们会自定义注解,并且需要配置拦截器对请求方法含有该自定义注解的方法进行拦截操作 自定义注解类 NeedToken.java import java.lang.annotation.Docume ...