golang中如何理解break与goto标签执行顺序

平时我们经常会用 for 和 select 语句来搭配使用来实现不断的通讯。
比如一个 goroutine 不断的从管道中发送字符,另一个不断的接收字符,当在管道关闭后,正常结束程序的执行。
如果我们不使用类似break, goto 等配合跳出到指定的标签,那么程序就不好控制正常结束了。
这里简要说明break,goto配合标签使用时的执行逻辑如下:
break是跳出到标签对应的当前指令,然后执行其下一条指令。
goto是跳往将要执行的指令。

goto + 标签

package main

import (
	"fmt"
	"time"
)

func main() {
	intChan := make(chan int)
	go func() {
		for i := 0; i < 5; i++ {
			time.Sleep(time.Second)
			intChan <- i
		}
		defer close(intChan)
	}()
	for {
		select {
		case i, ok := <-intChan:
			if !ok {
				fmt.Println("in break")
				goto LOOP
			}
			fmt.Println(i)
		case <-time.After(500 * time.Millisecond):
			fmt.Println("time expired")
		}
	}
LOOP:
	fmt.Println("end")
}

break + 标签

对于上述代码,如果我们想要使用break来改写,则如下

package main

import (
	"fmt"
	"time"
)

func main() {
	intChan := make(chan int)
	go func() {
		for i := 0; i < 5; i++ {
			time.Sleep(time.Second)
			intChan <- i
		}
		defer close(intChan)
	}()

	for {
		select {
		case i, ok := <-intChan:
			if !ok {
				fmt.Println("in break")
				break LOOP
			}
			fmt.Println(i)
		case <-time.After(500 * time.Millisecond):
			fmt.Println("time expired")
		}
	}
LOOP:
	fmt.Println("end")
}

但这样是不会通过编译的,显示如下:

# command-line-arguments
./breakloop.go:23:11: break label not defined: LOOP
./breakloop.go:30:1: label LOOP defined and not used

为什么呢?因为break这个不是goto,几乎可以到达程序的任何一个地方。它只能在其定义了后,才可以使用。

现在将其位置调整成如下,即可正常工作。

package main

import (
	"fmt"
	"time"
)

func main() {
	intChan := make(chan int)
	go func() {
		for i := 0; i < 5; i++ {
			time.Sleep(time.Second)
			intChan <- i
		}
		defer close(intChan)
	}()
LOOP:
	for {
		select {
		case i, ok := <-intChan:
			if !ok {
				fmt.Println("in break")
				break LOOP
			}
			fmt.Println(i)
		case <-time.After(500 * time.Millisecond):
			fmt.Println("time expired")
		}
	}
	fmt.Println("end")
}

上面的LOOP标签,就指代了当前的for{}语句,当用break LOOP时,其会跳过当前语句(for{}),而开始执行下一条语句(也即 fmt.Println("end"))
如此,则满足我们需求了。如果break时不带标签,那么其只退出当前的 select语句,无法跳出 for,就永远不会结束了。
总之,break LOOP,需要出现在LOOP所标志的那条语句中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值