
When it comes to iterating over a sequence of values or performing a task repeatedly, loops are an essential tool in any programming language. In Golang, loops are an integral part of the language and can be written in a variety of ways. In this article, we will explore the different for loops Golang has to offer, their syntax, and their use cases.
Syntax of a For Loop in Golang
The most commonly used loop in Go is the for loop. The syntax of a for loop in Go is as follows:
for initialization; condition; increment {
// code to be executed
}
The initialization
statement is executed once before the loop starts. It can be used to declare and initialize variables that will be used in the loop.
The condition
statement is a boolean expression that is evaluated before each iteration of the loop. If the expression is true, the loop continues to run. If it is false, the loop terminates.
The increment
statement is executed after each iteration of the loop. It can be used to modify the loop variable or perform some other action.
The code block to be executed is enclosed in curly braces and is executed for each iteration of the loop.
For Loops Golang Example
// Example 1: Looping through a sequence of values
numbers := []int{1, 2, 3, 4, 5}
for i := 0; i < len(numbers); i++ {
fmt.Println(numbers[i])
}
// Example 2: Performing a task repeatedly
for i := 0; i < 10; i++ {
fmt.Println("Hello, world!")
}
// Example 3: Looping over a string
text := "Hello, world!"
for i := 0; i < len(text); i++ {
fmt.Printf("%c ", text[i])
}
In Example 1, we loop through a slice of integers and print each value to the console. In Example 2, we print "Hello, world!" ten times and in Example 3, we loop over a string and print each character to the console.
The range Keyword in For Loops
In addition to the standard for loop syntax, Go provides a helpful shorthand syntax for iterating over a sequence of values using the range
keyword:
for index, value := range sequence {
// code to be executed
}
The index
variable is the index of the current value in the sequence and value
is the actual value itself. The sequence
can be an array, slice, string, or map.
// Example 1: Looping over a slice of integers
numbers := []int{1, 2, 3, 4, 5}
for index, value := range numbers {
fmt.Printf("Index: %d, Value: %d\n", index, value)
}
// Example 2: Looping over a string
text := "Hello, world!"
for index, value := range text {
fmt.Printf("Index: %d, Value: %c\n", index, value)
}
// Example 3: Looping over a map
m := map[string]int{"a": 1, "b": 2, "c": 3}
for key, value := range m {
fmt.Printf("Key: %s, Value: %d\n", key, value)
}
When using pointers, you will want to keep in mind that updating a pointer variable will result in all other loop iterations seeing this updated value. This could have the unintended consequence of violating the data integrety or consistency that you expected. To avoid this you may wish to read up on how to write a deep copy function in Golang.
The continue Statement in For Loops
Sometimes, you may want to skip an iteration of a loop based on a certain condition. In Go, you can use the continue
statement to skip the current iteration of a loop and move on to the next one. The continue
statement can be used in both standard for loops and range-based for loops.
Let's take a look at an example of how the continue statement can be used in a for loop:
// Example: Skipping even numbers
numbers := []int{1, 2, 3, 4, 5}
for _, value := range numbers {
if value%2 == 0 {
continue
}
fmt.Println(value)
}
In this example, we have a slice of integers and want to print only the odd numbers. We use the continue
statement within an if statement making use of modulo (%) to skip over any even numbers and only print the odd ones out.
The break Statement in For Loops
In addition to the continue
statement, Go also provides the break
statement, which can be used to terminate a loop early. When a break
statement is encountered in a loop, the loop immediately terminates, and the program continues executing from the statement following the loop.
// Example: Terminating a loop early
numbers := []int{1, 2, 3, 4, 5}
for _, value := range numbers {
if value == 3 {
break
}
fmt.Println(value)
}
In this example, we have a slice of integers and want to print all the values until we encounter the number 3. We use the break
statement to terminate the loop early when we encounter the number 3.
Using For Loops in Golang with a Map
For loops can also be used to iterate over maps in Go. Since Golang maps are unordered, the range keyword is used to iterate over the keys and values of a map in an arbitrary order. For each iteration, the key and value pairs are returned as separate variables. This makes it easy to loop through all the elements in a map and perform some operation on each one. For example, you can use a for loop to iterate over a map of user information and print out each user's name and age.
// Example: Iterating over a map using a for loop
users := map[string]int{
"Foo": 25,
"Bar": 30,
"Gopher": 35,
}
for name, age := range users {
fmt.Println("%s is %d years old\n", name, age)
}
In this example, we have a map called users
that contains the ages of three users. We use a for loop with the range
keyword to iterate over the map and print out each user's name and age. The range
keyword returns the key and value pairs of the map for each iteration of the loop, which are stored in the name
and age
variables, respectively. Finally, we use the Println
function to print out a formatted string for each user. The output of this code would be:
Bar is 30 years old
Foo is 25 years old
Gopher is 35 years old
Why are my for loops Golang maps unordered?
Maps in Go are implemented as hash tables, which use a hash function to map keys to their corresponding values in the underlying data structure. When iterating over a map, the Go developers made sure to return values in a random order since Go 1 to prevent developers depending on order reliability which may vary between platform implementations.
You can read more on the reasoning and justification on the Go 1 Release Notes section labelled Iterating in Maps, but in short when using maps in Go they are considered to be unordered.