Loops

Welcome to tutorial number 9 in Golang tutorial series.

A loop statement is used to execute a block of code repeatedly.

for is the only loop available in Go. Go doesn’t have while or do while loops which are present in other languages like C.

for loop syntax

for initialisation; condition; post {
}

The initialisation statement will be executed only once. After the loop is initialised, the condition will be checked. If the condition evaluates to true, the body of the loop inside the { } will be executed followed by the post statement. The post statement will be executed after each successful iteration of the loop. After the post statement is executed, the condition will be rechecked. If it’s true, the loop will continue executing, else the for loop terminates.

All the three components namely initialisation, condition and post are optional in Go. Let’s look at an example to understand for loop better.

Example

Let’s write a program that uses for loop to print all numbers from 1 to 10.

 1package main
 2
 3import (
 4	"fmt"
 5)
 6
 7func main() {
 8	for i := 1; i <= 10; i++ {
 9		fmt.Printf(" %d",i)
10	}
11}

Run in playground

In the above program, i is initialised to 1. The conditional statement will checks if i <= 10. If the condition is true, the value of i is printed, else the loop is terminated. The post statement increments i by 1 at the end of each iteration. Once i becomes greater than 10, the loop terminates.

The above program will print 1 2 3 4 5 6 7 8 9 10

The variables declared in a for loop are only available within the scope of the loop. Hence i cannot be accessed outside the body of the for loop.

break

The break statement is used to terminate the for loop abruptly before it finishes its normal execution and move the control to the line of code just after the for loop.

Let’s write a program that prints numbers from 1 to 5 using break.

package main

import (
	"fmt"
)

func main() {
	for i := 1; i <= 10; i++ {
		if i > 5 {
			break //loop is terminated if i > 5
		}
		fmt.Printf("%d ", i)
	}
	fmt.Printf("\nline after for loop")
}

Run in playground

In the above program, the value of i is checked during each iteration. If i is greater than 5 then break executes and the loop is terminated. The print statement just after the for loop is then executed. The above program will output,

1 2 3 4 5 
line after for loop

continue

The continue statement is used to skip the current iteration of the for loop. All code present in a for loop after the continue statement will not be executed for the current iteration. The loop will move on to the next iteration.

Let’s write a program to print all odd numbers from 1 to 10 using continue.

package main

import (
	"fmt"
)

func main() {
	for i := 1; i <= 10; i++ {
		if i%2 == 0 {
			continue
		}
		fmt.Printf("%d ", i)
	}
}

Run in playground

In the above program the line if i%2 == 0 checks if the remainder of dividing i by 2 is 0. If it is zero, then the number is even and continue statement is executed and the control moves to the next iteration of the loop. Hence the print statement after the continue will not be called and the loop proceeds to the next iteration. The output of the above program is 1 3 5 7 9

Nested for loops

A for loop which has another for loop inside it is called a nested for loop.

Let’s understand nested for loops by writing a program that prints the sequence below.

*
**
***
****
*****

The program below uses nested for loops to print the sequence. The variable n in line no. 8 stores the number of lines in the sequence. In our case it’s 5. The outer for loop iterates i from 0 to 4 and the inner for loop iterates j from 0 to the current value of i. The inner loop prints * for each iteration and the outer loop prints a new line at the end of each iteration. Run this program and you see the sequence printed as output.

 1package main
 2
 3import (
 4	"fmt"
 5)
 6
 7func main() {
 8	n := 5
 9	for i := 0; i < n; i++ {
10		for j := 0; j <= i; j++ {
11			fmt.Print("*")
12		}
13		fmt.Println()
14	}
15}

Run in playground

Labels

Labels can be used to break the outer loop from inside the inner for loop. Let’s understand what I mean by using a simple example.

 1package main
 2
 3import (
 4	"fmt"
 5)
 6
 7func main() {
 8	for i := 0; i < 3; i++ {
 9		for j := 1; j < 4; j++ {
10			fmt.Printf("i = %d , j = %d\n", i, j)
11		}
12
13	}
14}

Run in playground

The above program is self-explanatory and it will print

i = 0 , j = 1
i = 0 , j = 2
i = 0 , j = 3
i = 1 , j = 1
i = 1 , j = 2
i = 1 , j = 3
i = 2 , j = 1
i = 2 , j = 2
i = 2 , j = 3

Nothing special in this :)

What if we want to stop printing when i and j are equal. To do this we need to break from the outer for loop. Adding a break in the inner for loop when i and j are equal will only break from the inner for loop.

 1package main
 2
 3import (
 4	"fmt"
 5)
 6
 7func main() {
 8	for i := 0; i < 3; i++ {
 9		for j := 1; j < 4; j++ {
10			fmt.Printf("i = %d , j = %d\n", i, j)
11			if i == j {
12				break
13			}
14		}
15
16	}
17}

Run in playground

In the program above, I have added a break inside the inner for loop when i and j are equal in line no. 10. This will break only from the inner for loop and the outer loop will continue. This program will print.

i = 0 , j = 1
i = 0 , j = 2
i = 0 , j = 3
i = 1 , j = 1
i = 2 , j = 1
i = 2 , j = 2

This is not the intended output. We need to stop printing when both i and j are equal i.e when they are equal to 1.

This is where labels come to our rescue. A label can be used to break from an outer loop. Let’s rewrite the program above using labels.

 1package main
 2
 3import (
 4	"fmt"
 5)
 6
 7func main() {
 8outer:
 9	for i := 0; i < 3; i++ {
10		for j := 1; j < 4; j++ {
11			fmt.Printf("i = %d , j = %d\n", i, j)
12			if i == j {
13				break outer
14			}
15		}
16
17	}
18}

Run in playground

In the program above, we have added a label outer in line no. 8 on the outer for loop and in line no. 13 we break the outer for loop by specifying the label. This program will stop printing when both i and j are equal. This program will output

i = 0 , j = 1
i = 0 , j = 2
i = 0 , j = 3
i = 1 , j = 1

More examples

Let’s write some more code to cover all variations of for loop.

The program below prints all even numbers from 0 to 10.

package main

import (
	"fmt"
)

func main() {
	i := 0
	for ;i <= 10; { // initialisation and post are omitted
		fmt.Printf("%d ", i)
		i += 2
	}
}

Run in playground

As we already know all the three components of the for loop namely initialisation, condition and post are optional. In the above program, initialisation and post are omitted. i is initialised to 0 outside the for loop. The loop will be executed as long as i <= 10. i is increment by 2 inside the for loop. The above program outputs 0 2 4 6 8 10 .

The semicolons in the for loop of the above program can also be omitted. This format can be considered as an alternative for while loop. The above program can be rewritten as,

package main

import (
	"fmt"
)

func main() {
	i := 0
	for i <= 10 { //semicolons are ommitted and only condition is present
		fmt.Printf("%d ", i)
		i += 2
	}
}

Run in playground

It is possible to declare and operate on multiple variables in for loop. Let’s write a program that prints the below sequence using multiple variable declarations.

10 * 1 = 10
11 * 2 = 22
12 * 3 = 36
13 * 4 = 52
14 * 5 = 70
15 * 6 = 90
16 * 7 = 112
17 * 8 = 136
18 * 9 = 162
19 * 10 = 190
package main

import (
	"fmt"
)

func main() {
	for no, i := 10, 1; i <= 10 && no <= 19; i, no = i+1, no+1 { //multiple initialisation and increment
		fmt.Printf("%d * %d = %d\n", no, i, no*i)
	}

}

Run in playground

In the above program no and i are declared and initialised to 10 and 1 respectively. They are incremented by 1 at the end of each iteration. The boolean operator && is used in the condition to ensure that i is less than or equal to 10 and also no is less than or equal to 19.

infinite loop

The syntax for creating an infinite loop is,

for {
}

The following program will keep printing ```Hello World``` continuously without terminating.
package main

import "fmt"

func main() {
	for {
		fmt.Println("Hello World")
	}
}

If you try to run the above program in the go playground you will get error “process took too long”. Please try running it in your local system to print “Hello World” infinitely.

There is one more construct range which can be used in for loops for array manipulation. We will cover this when we learn about arrays.

That’s it for loops. Hope you enjoyed reading. Please leave your feedback and comments. Please consider sharing this tutorial on twitter and LinkedIn. Have a good day.

If you would like to advertise on this website, hire me, or if you have any other software development needs please email me at naveen[at]golangbot[dot]com.

Next tutorial - switch statement