一、踩得坑

	for {
time.Sleep(p.Cfg.WatchInterval)
select {
case <-ctx.Done():
return default:
err := p.watchSomeThing(ctx)
if err != nil {
p.Error(zap.Error(errors.Wrap(err, "watch something")))
//continue
break //TODO:临时修改
}
}
}

最近项目中有上面一段代码,本来是为了临时修改在出错的时候能够退出最外层的for循环,简单的使用break,结果实际测试的时候仍然不起作用。后面发现其实是自己对break的用法理解还是不够透彻。

二、break的使用

1、break用于for循环

/* for 循环 */
for a < 20 {
fmt.Printf("a 的值为 : %d\n", a);
a++;
if a > 15 {
/* 使用 break 语句跳出循环 */
break;
}
}

例如上面的一段代码,即利用break跳出一个for循环。

2、 break用于select

    select {
case <-ch:
fmt.Println("This case is selected.")
break //The following statement in this case will not execute.
fmt.Println("After break statement")
default:
fmt.Println("This is the default case.")
}

例如上面一段代码,即利用break跳出一个select循环

3、break用于嵌套循环

	stopLable:
for {
time.Sleep(p.Cfg.WatchInterval)
select {
case <-ctx.Done():
return default:
err := p.watchSomeThing(ctx)
if err != nil {
p.Error(zap.Error(errors.Wrap(err, "watch something")))
//continue
break stopLable//TODO:临时修改
}
}
}

在 switch 或 select 语句中,break语句的作用结果是跳过整个代码块,执行后续的代码。但是嵌套循环时,只会跳出最内层的循环,最外层的for循环还是一直在跑。要想跳出最外层的循环可以在 break 后指定标签。用标签决定哪个循环被终止。

4、break label 、 goto label 、continue label

break label 和 goto label都能在循环中跳出循环,但是又有些不同之处。

  • break label:跳转标签(label)必须放在循环语句for前面,并且在break label跳出循环不再执行for循环里的代码。且break标签只能用于for循环
package main

import "fmt"

func main() {
outLable:
for i:=0; i< 5; i++{
fmt.Printf("外层:第%d次外层循环\n", i)
for j:=0; j< 5; j++ {
fmt.Printf("内层:第%d次内层循环\n", j)
break outLable
}
fmt.Printf("外层:没有跳过第%d次循环\n", i)
}
}

输出:

外层:第0次外层循环
内层:第0次内层循环
  • continue label: :跳转标签(label)必须放在循环语句for前面,跳出循环后则将继续执行lable后面的代码,即开始下一次外层循环
package main

import "fmt"

func main() {
outLable:
for i:=0; i< 5; i++{
fmt.Printf("外层:第%d次外层循环\n", i)
for j:=0; j< 5; j++ {
fmt.Printf("内层:第%d次内层循环\n", j)
continue outLable
}
fmt.Printf("外层:没有跳过第%d次循环\n", i)
}
}

输出:

外层:第0次外层循环
内层:第0次内层循环
外层:第1次外层循环
内层:第0次内层循环
外层:第2次外层循环
内层:第0次内层循环
外层:第3次外层循环
内层:第0次内层循环
外层:第4次外层循环
内层:第0次内层循环
  • goto lable:既可以定义在for循环前面,也可以定义在for循环后面,当跳转到标签地方时,继续执行标签下面的代码。
package main

import "fmt"

func main() {
outLable:
for i:=0; i< 5; i++{
fmt.Printf("外层:第%d次外层循环\n", i)
for j:=0; j< 5; j++ {
fmt.Printf("内层:第%d次内层循环\n", j)
goto outLable
}
fmt.Printf("外层:没有跳过第%d次循环\n", i)
}
}

输出:

外层:第0次外层循环
内层:第0次内层循环
外层:第0次外层循环
内层:第0次内层循环
外层:第0次外层循环
内层:第0次内层循环
外层:第0次外层循环
内层:第0次内层循环
外层:第0次外层循环
内层:第0次内层循环
......

5、官方解释

Break statements

A “break” statement terminates execution of the innermost “for”, “switch”, or “select” statement within the same function.

BreakStmt = “break” [ Label ] .

If there is a label, it must be that of an enclosing “for”, “switch”, or “select” statement, and that is the one whose execution terminates.

OuterLoop:
for i = 0; i < n; i++ {
for j = 0; j < m; j++ {
switch a[i][j] {
case nil:
state = Error
break OuterLoop
case item:
state = Found
break OuterLoop
}
}
}

Continue statements

A “continue” statement begins the next iteration of the innermost “for” loop at its post statement. The “for” loop must be within the same function.

ContinueStmt = “continue” [ Label ] .

If there is a label, it must be that of an enclosing “for” statement, and that is the one whose execution advances.

RowLoop:
for y, row := range rows {
for x, data := range row {
if data == endOfRow {
continue RowLoop
}
row[x] = data + bias(x, y)
}
}

Goto statements

A “goto” statement transfers control to the statement with the corresponding label within the same function.

GotoStmt = “goto” Label .

goto Error

Executing the “goto” statement must not cause any variables to come into scope that were not already in scope at the point of the goto. For instance, this example:

	goto L  // BAD
v := 3
L:
is erroneous because the jump to label L skips the creation of v.

A “goto” statement outside a block cannot jump to a label inside that block. For instance, this example:

if n%2 == 1 {
goto L1
}
for n > 0 {
f()
n--
L1:
f()
n--
}

is erroneous because the label L1 is inside the “for” statement’s block but the goto is not.

参考文章

1、In Go, does a break statement break from a switch/select?

2、https://golang.org/ref/spec#Break_statements

3、Go语言之continue/break label(五)

go break的使用的更多相关文章

  1. continue break 区别

    在循环中有两种循环方式 continue , break continue 只是跳出本次循环, 不在继续往下走, 还是开始下一次循环 break  将会跳出整个循环, 此循环将会被终止 count = ...

  2. C# 中Switch case 返回不止用break

    Switch(temp) { case "A": //跳出循环 break; case "B": //返回值 return var; case "C& ...

  3. jquery each函数 break和continue功能

    jquery each函数 break和continue功能幸运的是另一个突破,持续一个jQuery循环方式.你可以打破在函数返回一个jQuery参数虚假循环.一个可以继续执行只是在做不指定返回值或返 ...

  4. [LeetCode] Integer Break 整数拆分

    Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...

  5. [LeetCode] Word Break II 拆分词句之二

    Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ...

  6. R for循环之break,next

    next跳出本次循环 break跳出本层循环(当有多个for 循环时,即跳出最近的一个for循环)

  7. 关于break语句如何结束多重循环的嵌套

    在Java中的break语句功能大体上同c语言, 用于循环语句中,表示结束当前循环. 但是有时候在循环嵌套语句中,仅仅靠一 个break语句想实现是不够的. 例: 如果想使sum在501时就直接输出, ...

  8. break与continue的区别

    break       在while.for.do...while.while循环中使用break语句退出当前循环,直接执行后面的代码. continue   的作用是仅仅跳过本次循环,而整个循环体继 ...

  9. 高程(3):操作符、for、for...in循环、break/continue/return语句、函数等

    1.关系操作符 注意点:1)比较操作数是两个字符串,是比较字符串的字符编码值. 如:"a" > "b"  返回 false:"a" & ...

  10. case break结构与return的有关要点

    //确认事件 private void cmd_ok_Click(object sender, EventArgs e) { //客户名称是否为空 if (txt_banhao.Text.TrimEn ...

随机推荐

  1. python——字符串操作函数

    字符串 join() map() split() rsplit() splitlines() partiton() rpartition() upper() lower() swapcase() ca ...

  2. pssh系列工具

    一.pssh简介及安装 首先我们来了解下什么是pssh,它是干嘛用的?pssh是一个python编写可以在多台服务器上执行命令的工具,也可以实现文件复制.换而言之就是一个批量管理多台服务器的一个小工具 ...

  3. containerd 与安全沙箱的 Kubernetes 初体验

    作者 | 易立  阿里云资深技术专家 containerd 是一个开源的行业标准容器运行时,关注于简单.稳定和可移植,同时支持 Linux 和 Windows. 2016 年 12 月 14 日,Do ...

  4. 02. JVM运行机制

    JVM运行机制 JVM启动流程 JVM基本结构 内存模型 编译和解释运行的概念 一.JVM启动流程

  5. Linux入门之简介

    1.啥是linux? Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和Unix的多用户.多任务.支持多线程和多CPU的操作系统. 它能运行主要的Unix工具软件.应用程序 ...

  6. [转发]CSR 量产 烧录 软件

    蓝牙量产软件主要是为了应对蓝牙设备在批量生产时的一些如固件下载,地址下载,名字修改,以及一些辅助测试和检验功能. 目前,CSR推出的蓝牙芯片按照存储介质以及可编程与否分为两大类:ROM版本和Flash ...

  7. HTML_本地存储

    在HTML5当中,新增了很多的存储方式,这里我先介绍两种,方便我们的使用和操作,具体新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问 ...

  8. URL基本语法

    1.URL全称为Uniform Resource Locator,即统一资源定位符.对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址.互联网上的每个文件都有一个唯一 ...

  9. enable_shared_from_this用法分析

    一.背景 在为什么需要异步编程文章末尾提到,"为了使socket和缓冲区(read或write)在整个异步操作的生命周期一直保持活动,我们需要采取特殊的保护措施.你的连接类需要继承自enab ...

  10. ctf线下赛中检测外来IP的shell脚本

    该脚本可用于ctf线下赛中,用来检测攻击IP的接入,及时做出响应. #!/bin/bash #写自己队的ip ipA="172.22.60.230" ipB="172.2 ...