4. Control Structures

4.1 if-else

Program: cs1.go


 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6 	x, y := 30, 45
 7 	if x < y {
 8 		fmt.Println("x is less than y")
 9 	} else if x > y {
10 		fmt.Println("x is greater than y")
11 	} else {
12 		fmt.Println("x is equal to y")
13 	}
14 }

Run the above program and the output that you will see is:

x is less than y

Note:

  • There may be zero or more else if clauses and zero or one final else clause. Each block consists of zero or more statements.
  • The expression after the if and the else if has to evaluate to one of the bool types: true or false.
  • There are no parentheses required around the boolean expression - you can have a parentheses, but you don’t have to have it.
  • Go requires the curly braces and the if else keywords to be on the same line with the corresponding braces. If not you will see errors.
  • You can have the explicit values like true or false, or you can also use any expression that evaluates to a true or false.
  • Note that types like an int cannot be used as truth values - this is unlike languages like C, where you can use integers and pointers as truth values.

4.2 goto statement

Go has a goto statement, which you should use wisely. With goto you jump to a label which must be defined within the current function. For instance:

Program: cs2.go


 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6         i := 0
 7 Label:                // First word on a line ending with a colon is a label
 8         fmt.Println(i)
 9         i++
10         if i > 50 {
11                 goto Escape
12         }
13 
14         goto Label   // Jump
15 Escape:              // Label
16         fmt.Println("Get out of here...")
17 }

The name of the label is case sensitive.

4.3 switch

The general format of the switch is:

1 switch any expression of type T {
2 case any expression of same type T: { code to be executed if the case expression is equal \
3 to the switch expression }
4 case any expression of same type T: { code to be executed if this case expression is equal\
5  to the switch expression }
6 //any number of case statements are allowed
7 default: { code to be executed if none of the case expressions match the switch expression\
8  }
9 }

Points to note:

  • the type of the evaluated value in the switch and the case should match. For example, if the switch expression evaluates to an int and the case expression evaluates to a string, then there will be a compile error
  • if there is no expression at all in the switch, then by default it is bool. The block that evaluates to true is executed, and none of the others are executed
  • if more than one case statements match, then the first in the lexical order is executed
  • unlike certain other languages, each case block is independent and the code does not “fall through” (each of the case code blocks are like independent if-else code blocks.)
  • the default code block is executed if none of the other case blocks match
  • the case expressions need not be just constants and can have expressions
  • the use of curly braces for demarcating the code blocks is optional
  • the default statement is optional
  • any number of case statements are allowed - even zero case statements are valid, though that wouldn’t be very useful
  • multiple expressions can be used, each separated by commas in the case statement
  • the default block can be anywhere within the switch block, and not necessarily last in the lexical order

Exercise 6

Explain why the program displays the output as “I am true” in the following program:

Program: cs3.go


 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6     switch {
 7     default: fmt.Println("I am default")
 8     case false: fmt.Println("I am false")
 9     case true: fmt.Println("I am true")
10     }
11 }

Exercise 7

Explain why the following program does not compile:

Program: cs4.go


 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6     i := 5
 7     switch i {
 8     case 4: fmt.Println("number 4")
 9     case i > 8: fmt.Println("i is > 8")
10     default: fmt.Println("default")
11     }
12 }

4.3.1 fallthrough statement

In certain languages like C and Java, the switch-case statement behaves slightly differently from Go: when a case block is executed, all the case blocks below it are also executed, unless explicitly terminated (by say using a break statement). In Go, this is not the default behavior, but if you want to achieve the same result, then use the fallthrough statement to indicate that the case block following the current one has to be executed.

1 k := 3
2 switch k {
3 case 3: fmt.Println("was <= 3"); fallthrough;
4 case 4: fmt.Println("was <= 4"); fallthrough;
5 ...

4.4 for loop

Go has only one looping construct, the for loop.

The basic for loop looks as it does in C or Java, except that the ( ) are gone (they are not even optional) and the { } are required.

There are three forms of for, only one of which has semicolons.

1 // Like a C for
2 for init; condition; post { }
3 
4 // Like a C while
5 for condition { }
6 
7 // Like a C for(;;)
8 for {
9 }

Here’s an example:

Program: cs5.go


 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6         sum := 0
 7         for i := 0; i < 100; i++ {
 8                 sum += i
 9         }
10         fmt.Println(sum)
11 }

The output of the program is 4950.

The above program is available here1.

Here are some code snippets and their explanation:

1 func main() {
2         sum := 1
3         // As in C or Java, you can leave the
4         // pre and post statements empty.
5         for ; sum < 100; {
6                 sum += sum
7         }
8         fmt.Println(sum)
9 }
1 func main() {
2         sum := 1
3         // You can drop the semicolons
4         // for behaves like C's while
5         for sum < 1000 {
6                 sum += sum
7         }
8         fmt.Println(sum)
9 }
1 func main() {
2         // infinite loop
3         for {
4         }
5 }

The break keyword allows you to terminate a loop at a point and continue execution at the statement following the end of the for loop block.

An example:

Program: cs6.go


 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6 	i := 0
 7 	for {
 8 		if i >= 10 {
 9 			break
10 		}
11 		fmt.Println("Value of i is:", i)
12 		i++
13 	}
14 	fmt.Println("A statement just after the for loop.")
15 }

With the continue keyword you begin the next iteration of the loop, skipping any remaining code. In the same way as break, continue also accepts a label.

The following loop prints 0 to 5.

Program: cs7.go


 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6 	for i := 0; i < 10; i++ {
 7 		if i > 5 {
 8 			// Skip the rest of the remaining code in the loop
 9 			continue
10 		}
11 		fmt.Println(i)
12 	}
13 }

A nested for loop example:

Program: cs8.go


 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6 L:
 7 	for {
 8 		for {
 9 			break L
10 		}
11 	}
12 	fmt.Println("Break out of nested loops")
13 }

Exercise 8

Write a program that uses the continue keyword in a for loop to print only even numbers up to 100.

Exercise 9

  1. Create a simple loop with the for construct. Make it loop 5 times and print out the loop counter with the fmt package.
  2. Rewrite the above to use goto. for is not to be used here.

Exercise 10

Create a Go program that prints the following (up to 10 characters):

O
OO
OOO
OOOO
OOOOO
OOOOOO
OOOOOOO
OOOOOOOO
OOOOOOOOO
OOOOOOOOOO

4.5 Solutions

Exercise 6 Reason: If there is no expression at all in the switch, then by default it is bool. The block that evaluates to true is executed, and none of the others are executed.

Exercise 7 Reason: The program will not compile as the type int and bool don’t match between the case and the switch.

Exercise 8 Solution2.

Exercise 9 Solutions. Part a3 and Part b4.

Exercise 10 Solution5.

  1. http://play.golang.org/p/Pixi9AFeX6
  2. http://play.golang.org/p/qN6fy8LSUb
  3. https://play.golang.org/p/7X5VQM1b7p
  4. https://play.golang.org/p/IclWz08hNa
  5. https://play.golang.org/p/Tg6oG0pVDt