# Break out of Nested Loops in Go


🗓 November 21, 2018 | 👱 By: Hugh



How do you break out of nested loops in Go? A simple break sometimes just won't do!

One example where I run into this issue is in in a ticker function like below, unfortunately it doesn't behave as you might think:

package main
import (
	"fmt"
	"time"
)
func main() {
	stop := make(chan interface{})
	go func() {
		for {
			select {
			case <-time.After(time.Second):
				fmt.Println("tick")
			case <-stop:
				fmt.Println("stopping")
				break
			}
		}
		fmt.Println("stopped")
	}()
	time.Sleep(3 * time.Second)
	stop <- true
	time.Sleep(3 * time.Second)
}

You might expect the output to be along the lines of:

tick
tick
tick
stopping
stopped

WRONG!

Instead you'll see the following:

tick
tick
tick
stopping
tick
tick
tick

Check it out here.



The break only breaks out of the select, but the for loop continues indefinitely! To break out of the for, we need to use a label, like so:

package main
import (
	"fmt"
	"time"
)
func main() {
	stop := make(chan interface{})
	go func() {
	ForLoop:
		for {
			select {
			case <-time.After(time.Second):
				fmt.Println("tick")
			case <-stop:
				fmt.Println("stopping")
				break ForLoop
			}
		}
		fmt.Println("stopped")
	}()
	time.Sleep(3 * time.Second)
	stop <- true
	time.Sleep(3 * time.Second)
}

The output is now as expected:

tick
tick
tick
stopping
stopped

Try it out here!