理解Go语言中break语句是如何工作的

本文探讨了在Go语言中,如何正确使用break语句中断for、switch或select语句,特别是强调了标签在避免错误中断循环中的重要性。
摘要由CSDN通过智能技术生成

        break语句常用来中断循环。当循环与switch或select一起使用时,开发者经常执行了错误的break语句。

        让我们来看下面的示例。我们在for循环里使用了switch,如果循环索引值是2,那么我们想中断循环:

package main

import (
	"fmt"
)

func main() {
	for i := 0; i < 5; i++ {
		fmt.Printf("%d ", i)

		switch i {
		default:
		case 2:
			break
		}
	}
}

 这段代码乍一看没什么问题;然而,它不像我们想象的那样运作。break语句没有中断for循环,而是中断了switch语句。因此这段代码从0迭代到4:0 1 2 3 4,而不是从0 迭代到2。

        要记住的一个基本规则是,break语句终止最里面的for、switch或select语句,在上面的例子中,它中断的是switch语句。

那如何跳出循环而不是switch语句呢?最常用的方式是使用标签:

package main

import (
	"fmt"
)

func main() {
loop:
	for i := 0; i < 5; i++ {
		fmt.Printf("%d ", i)

		switch i {
		default:
		case 2:
			break loop
		}
	}
}

这里,我们将loop标签与for循环关联起来。然后,由于我们给break语句提供了loop标签,它跳出了循环而不是switch语句,因此这个正如我们期望的,打印0 1 2。

带标签的break和goto一样吗?

        一些开发者可能会质疑使用带标签的break是否是习惯用法,并把它当作花哨的goto语句,然而,事实并非如此,这样的代码也在标准库中被使用。比如在net/http包中,从一个缓冲区中按行读取:

readlines:
	for {
		line,err := rw.Body.ReadString('\n')
		switch {
			case err == io.EOF:
				break readlines
			case err != nil:
				t.Fatalf("unexpected error reading from CGI: %v",err)
		}
		//...
	}

这个例子使用了简明的readlibes标签来强调循环的目标。因此,我们应该认为,在Go中使用标签中断语句是一个习惯用法。

        break 语句也可能错误地出现在循环内的select语句中。在下面这段代码中,我们想用带有两个case的select语句,在上下文被取消时退出循环:

for {
	select {
		case <-ch:
			//做具体操作
		case <-ctx.Done():
			break	//如果上下文被取消则中断执行
	}
}

这里,最里面的for、switch或select语句是select语句,而不是for循环。所以循环仍重复进行。同样地,我们可以使用标签中断循环:

loop:	//定义循环标签
for {
	select {
		case <-ch:
			//做具体操作
		case <-ctx.Done():
			break loop 	//终止loop标签关联的循环,而不是select
	}
}

现在和预期一致,break语句跳出了循环而不是跳出select 语句。

        在循环中使用switch或select时要保持谨慎。当使用break时,应始终确保我们知道哪个语句会受影响,正如我们看到的,使用标签强制退出特定语句是惯用的解决方案。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mindfulness code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值