5 minute read

Go Flow Control Statements

In this post, let us go through some of the flow control features of Go language.

For Loop

Go has only one looping construct, the for loop.

The basic for loop has three components separated by semicolons:

  • the init statement: executed before the first iteration
  • the condition expression: evaluated before every iteration
  • the post statement: executed at the end of every iteration

The init statement will often be a short variable declaration, and the variables declared there are visible only in the scope of the for statement.

The loop will stop iterating once the boolean condition evaluates to false.

Note: Unlike other languages like C, Java, or JavaScript there are no parentheses surrounding the three components of the for statement and the braces { } are always required.

Here is a simple For loop to print the sume of numbers 0 to 9.

pradeep@LearnGo example % cat for.go 
package main

import "fmt"

func main() {
	sum := 0
	for i := 0; i < 10; i++ {
		sum += i
	}
	fmt.Println(sum)
}

pradeep@LearnGo example % go run for.go 
45

The init and post statements are optional.

So let us try a modified version of the above.

pradeep@LearnGo example % cat for-1.go 
package main

import "fmt"

func main() {
	sum := 1
	for ; sum < 45; {
		sum += sum
	}
	fmt.Println(sum)
}

pradeep@LearnGo example % go run for-1.go 
64

For is Go’s “while”

At that point you can drop the semicolons: C’s while is spelled for in Go.

pradeep@LearnGo example % cat for-2.go 
package main

import "fmt"

func main() {
	sum := 1
	for sum < 45 {
		sum += sum
	}
	fmt.Println(sum)
}
pradeep@LearnGo example % go run for-2.go 
64

If you omit the loop condition it loops forever, so an infinite loop is compactly expressed.

pradeep@LearnGo example % cat forever.go 
package main

func main() {
	for {
	}
}
pradeep@LearnGo example % go run forever.go 
^Csignal: interrupt

If Else

Go’s if statements are like its for loops; the expression need not be surrounded by parentheses ( ) but the braces { } are required.

pradeep@LearnGo example % cat if.go 
package main

import (
	"fmt"
)

var x int
func main() {
        if x < 10 {
           fmt.Println(x)
           fmt.Println("Less than 10")
} else {
  fmt.Println(x)
  fmt.Println("Greater than or equal to 10")
   
}
}
pradeep@LearnGo example % go run if.go
0
Less than 10

Since we have not initialized the variable x in this code, it will be assigned a value of 0 and the if condition results in true, hence the if code block got executed.

Let us change the value of variable x.

pradeep@LearnGo example % cat if-else.go 
package main

import (
	"fmt"
)

var x int
func main() {
        if x := 20; x < 10 {
           fmt.Println(x)
           fmt.Println("Less than 10")
} else {
  fmt.Println(x)
  fmt.Println("Greater than or equal to 10")
   
}
}

pradeep@LearnGo example % go run if-else.go 
20
Greater than or equal to 10

Like for, the if statement can start with a short statement to execute before the condition.

Variables declared by the statement are only in scope until the end of the if.

We can see that Variables declared inside an if short statement are also available inside any of the else blocks.

Switch

A switch statement is a shorter way to write a sequence of if - else statements. It runs the first case whose value is equal to the condition expression.

Go’s switch is like the one in C, C++, Java, JavaScript, and PHP, except that Go only runs the selected case, not all the cases that follow. In effect, the break statement that is needed at the end of each case in those languages is provided automatically in Go. Another important difference is that Go’s switch cases need not be constants, and the values involved need not be integers.

Here is an example showing the usage of switch in Go.

pradeep@LearnGo example % cat switch.go 
package main

import (
	"fmt"
	"runtime"
)

func main() {
	fmt.Print("Go runs on ")
	switch os := runtime.GOOS; os {
	case "darwin":
		fmt.Println("OS X.")
	case "linux":
		fmt.Println("Linux.")
	default:
		// freebsd, openbsd,
		// plan9, windows...
		fmt.Printf("%s.\n", os)
	}
}

pradeep@LearnGo example % go run switch.go 
Go runs on OS X.

Switch cases evaluate cases from top to bottom, stopping when a case succeeds.

For example,

switch i {
case 0:
case f():
}

does not call f if i==0.

The following example shows the order of evaluation

pradeep@LearnGo example % cat switch-order.go 
package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("When's Saturday?")
	today := time.Now().Weekday()
	switch time.Saturday {
	case today + 0:
		fmt.Println("Today.")
	case today + 1:
		fmt.Println("Tomorrow.")
	case today + 2:
		fmt.Println("In two days.")
	default:
		fmt.Println("Too far away.")
	}
}

Pradeep@LearnGo example % go run switch-order.go 
When's Saturday?
Too far away.

Switch without a condition is the same as switch true.

This construct can be a clean way to write long if-then-else chains.

pradeep@LearnGo example % cat switch-no-condition.go 
package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Now()
	switch {
	case t.Hour() < 12:
		fmt.Println("Good morning!")
	case t.Hour() < 17:
		fmt.Println("Good afternoon.")
	default:
		fmt.Println("Good evening.")
	}
}

pradeep@LearnGo example % go run switch-no-condition.go 
Good morning!

Defer

A defer statement defers the execution of a function until the surrounding function returns.

The deferred call’s arguments are evaluated immediately, but the function call is not executed until the surrounding function returns.

pradeep@LearnGo example % cat defer.go 
package main

import "fmt"

func main() {
	defer fmt.Println("world")

	fmt.Println("hello")
}
pradeep@LearnGo example % go run defer.go 
hello
world

Deferred function calls are pushed onto a stack. When a function returns, its deferred calls are executed in last-in-first-out order.

pradeep@LearnGo example % cat defer-multi.go 
package main

import "fmt"

func main() {
	fmt.Println("counting")

	for i := 0; i < 10; i++ {
		defer fmt.Println(i)
	}

	fmt.Println("done")
}
pradeep@LearnGo example % go run defer-multi.go 
counting
done
9
8
7
6
5
4
3
2
1
0
pradeep@LearnGo example % 

This concludes the discussion on how to control the flow of our code with conditionals, loops, switches and defers.

Back to Top ↑