Golang For Loop: Iterate Over Data Structures Read it later

5/5 - (2 votes)

In this blog post, we will be discussing the Golang For Loop. Loops are a fundamental part of any programming language, including Golang. They are used to iterate over a set of instructions repeatedly until a certain condition is met. Golang has several types of loops, each with its own unique characteristics and uses cases. Let’s explore them in detail.

What is a Loop in Golang?

A loop in Golang is a control structure that enables a program to execute a set of statements repeatedly.

It allows us to iterate over a set of data and execute a specific block of code repeatedly until a particular condition is met.

Types of For Loop in Golang

In Golang, there are three types of loops: for, while, and do-while.

1. Golang For Loop

The for loop is the most commonly used loop in Golang. It is used to execute a set of statements repeatedly until a specific condition is met.

Golang For Loop Syntax

for initialization; condition; post {
    // Statements
}
  • The initialization statement initializes the loop variable and is executed once before the loop starts.
  • The condition statement is evaluated at the beginning of each iteration. If it evaluates to true, the loop continues. If it evaluates to false, the loop terminates.
  • The post statement is executed after each iteration and is typically used to increment or decrement the loop variable.

Example:

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

In this example, we use a for loop to print the numbers 0 through 4 to the console. The loop starts with an initialization statement (i := 0), followed by a condition (i < 5), and an increment statement (i++).

2. While Loop in Go

The while loop in Golang is similar to the for loop, except that it only has a condition and no initialization or increment statement.

Golang While Loop Syntax

for condition {
    // statements to execute while condition is true
}

In the above syntax, condition is the expression that is evaluated before each iteration of the loop. If condition evaluates to true, the statements inside the loop are executed. If condition evaluates to false, the loop exits and the program continues with the next statement after the loop.

Example:

i := 0
for i < 5 {
    fmt.Println(i)
    i++
}

In this example, we use a while loop to print the numbers 0 through 4 to the console. The loop only has a condition (i < 5), and the increment statement (i++) is placed inside the loop body.

3. Do-While Loop

Golang does not have a built-in do-while loop like some other programming languages. However, we can simulate a do-while loop using a for loop with a break statement.

i := 0
for {
    // Statements
    fmt.Println(i)
    i++
    if i >= 5 {
        break
    }
}

In this example, we use a for loop to print the numbers 0 through 4 to the console. The loop has no condition, and the break statement is used to exit the loop when i is equal to or greater than 5.

Golang Infinite For loop

An infinite loop is a type of loop that continues to execute indefinitely. It is typically used in situations where the loop must continue until an external condition is met or when a particular block of code must execute repeatedly. In Golang, we can create an infinite loop using the for loop without any condition.

Go Infinite Loop Example

package main

import "fmt"

func main() {
    for {
        fmt.Println("This is an infinite loop")
    }
}

In this example, we use the for loop without any condition, which means the loop will continue to execute indefinitely. The fmt.Println() statement will repeatedly print the message “This is an infinite loop” to the console.

Golang Infinite For Loop Exit

To break out of an infinite loop, we can use the break statement.

package main

import "fmt"

func main() {
    for {
        fmt.Println("This is an infinite loop")
        break
    }
    fmt.Println("This statement will execute after breaking out of the infinite loop")
}

In this example, we use the break statement to break out of the infinite loop after the first iteration. The second fmt.Println() statement will execute after breaking out of the loop.

It’s important to note that an infinite loop can cause a program to crash or become unresponsive if not used correctly. It’s essential to ensure that the loop has a mechanism to exit, such as using the break statement or a conditional statement.

Golang For Loop Multiple Initialization

In Golang, the for loop allows you to initialize multiple variables in a single line separated by a comma.

package main

import "fmt"

func main() {
    for i, j := 0, 0; i < 5; i, j = i+1, j+2 {
        fmt.Println(i, j)
    }
}

In this example, we initialize two variables i and j to 0 in a single line separated by a comma. The for loop then executes the statements inside the block as long as i < 5. After each iteration, we increment i by 1 and j by 2.

You can also use this technique to initialize variables with different types.

package main

import "fmt"

func main() {
    for i, j := 0, "Golang"; i < 5; i, j = i+1, j+" Rocks!" {
        fmt.Println(i, j)
    }
}

In this example, we initialize two variables i of type int and j of type string. We then use the for loop to concatenate the string ” Rocks!” to the value of j after each iteration.

By using multiple initializations in a for loop, you can write more concise and readable code while iterating over multiple variables simultaneously.

Golang For Loop Using Range

Range in Golang is a built-in function that allows us to iterate over a data structure such as an array, slice, or map. It returns two values: the index and the value at that index.

Golang Range Syntax

for index, value := range collection {
    // code to be executed
}

In this syntax, index represents the index of the current iteration, value represents the value at the current index, and collection represents the data structure we want to iterate over.

Skipping the Index in Range

To skip the index in the range statement, we simply omit the index variable using Golang’s Blank Identifier _ and only declare the value variable.

package main

import "fmt"

func main() {
    nums := []int{1, 2, 3, 4, 5}
    for _, num := range nums {
        fmt.Println(num)
    }
}

In this example, we use the slice nums and iterate over each item using the range statement. However, notice that we have replaced the index variable with an underscore _ (Blank Identifier in Golang).

This tells Golang that we do not need to use the index variable in our code block, and it should be ignored. This way, we can access only the value of each item in the slice.

Golang For Loop Label

Golang provides loop labels to identify them when there are multiple nested loops. A label is a name assigned to a loop statement.

In some cases, you may need to break out of a loop prematurely. For example, you may need to break out of a loop if a certain condition is met.

In Golang, you can use the break keyword to exit a loop. However, if you have nested loops, the break keyword will only exit the innermost loop. To exit an outer loop, you can use a label with the break keyword.

package main

import "fmt"

func main() {
    outerLoop:
    for i := 1; i <= 3; i++ {
        for j := 1; j <= 3; j++ {
            fmt.Printf("i = %d, j = %d\n", i, j)
            if i == 2 && j == 2 {
                break outerLoop
            }
        }
    }
}

In this example, we use the outerLoop label to break out of both nested loops when i equals 2 and j equals 2. Without the label, the break statement would only break out of the inner loop. However, with the label, it breaks out of the outer loop as well.

We can also use the label to continue the loop statement.

Example:

package main

import "fmt"

func main() {
    outerLoop:
    for i := 1; i <= 3; i++ {
        for j := 1; j <= 3; j++ {
            if i == 2 && j == 2 {
                continue outerLoop
            }
            fmt.Printf("i = %d, j = %d\n", i, j)
        }
    }
}

In this example, we use the outerLoop label to continue the loop statement when i equals 2 and j equals 2. Without the label, the continue statement would only continue the inner loop. However, with the label, it continues the outer loop as well.

Golang Loop Using goto

The goto statement in Golang allows you to jump to a labeled statement in the same function, bypassing the normal flow of control. While the use of goto can make code harder to read and maintain, there are some situations where it can be useful, especially in loops.

The syntax for goto in Golang is simple. You specify the label you want to jump to with a colon at the end, like this:

goto label

And you define the label with the same syntax, as:

label:

Here’s an example of using goto in a Golang for loop:

package main

import "fmt"

func main() {
    i := 0
loop:
    if i < 5 {
        fmt.Println(i)
        i++
        goto loop
    }
}

In this example, we use goto to create an infinite loop that prints the values 0 through 4. We initialize i to 0 and define the label loop. We then use an if statement to check if i is less than 5. If it is, we print the value of i, increment i by 1, and jump back to the loop label using goto. This process continues until i is no longer less than 5.

While the use of goto can make code harder to read and maintain, and it can be useful in certain situations. For example, it can be used to exit nested loops or break out of a loop based on a condition that is not directly related to the loop’s condition.

Using Defer in Golang Loop

Defer is a Golang keyword that enables us to defer the execution of a function until the surrounding function returns. It is a powerful feature that can be used to handle resource cleanup, logging, and error handling, among other things.

In a Golang for loop, defer statements are executed after the loop finishes executing.

package main

import "fmt"

func main() {
    for i := 0; i < 5; i++ {
        defer fmt.Println("Deferred", i)
        fmt.Println(i)
    }
}

In this example, we use a for loop to print the values 0 through 4. We also use the defer keyword to defer the execution of the fmt.Println("Deferred", i) statement until the surrounding function returns. As a result, the deferred statements are executed in reverse order after the for loop finishes executing.

Output:

0
1
2
3
4
Deferred 4
Deferred 3
Deferred 2
Deferred 1
Deferred 0

As we can see from the output, the fmt.Println("Deferred", i) statements are executed in reverse order after the for loop completes. This is because deferred statements are executed in the reverse order they were deferred.

Golang For Loop Over String

Golang loops can also be used to loop through strings. In Go, strings are represented as a sequence of Unicode code points, and we can use loops to access each code point in the string.

package main

import "fmt"

func main() {
    str := "hello, world"
    for i, r := range str {
        fmt.Printf("index: %d, value: %c\n", i, r)
    }
}

In this example, we define a string variable str with the value “hello, world”. We then use the for range loop to iterate over each character in the string. The for range loop returns two values: the index of the current code point and the value of the current code point. We use the %d and %c format verbs to print the index and character value, respectively.

One thing to note when looping through strings in Golang is that strings are immutable. This means that we cannot change the value of a character in a string directly. However, we can create a new string by concatenating substrings and modifying them as necessary.

package main

import "fmt"

func main() {
    str := "hello, world"
    var newStr string
    for _, r := range str {
        if r == 'o' {
            newStr += "0"
        } else {
            newStr += string(r)
        }
    }
    fmt.Println(newStr)
}

In this example, we create a new string newStr by iterating over the characters in the original string str. If the current character is ‘o’, we replace it with ‘0’ in the new string. Otherwise, we append the current character to the new string using the += operator. Finally, we print the new string.

Golang For Loop Over Arrays

In Golang, an array is a fixed-size sequence of elements of the same type. To loop through an array, we can use the range keyword to iterate over the values.

package main

import "fmt"

func main() {
    arr := [3]int{1, 2, 3}
    for i, v := range arr {
        fmt.Println("Index:", i, "Value:", v)
    }
}

In this example, we define an array of length 3, initialize it with values 1, 2, and 3, and then use the for i, v := range arr loop to loop through the array. The i variable represents the index of the current element and v represents the value of the current element.

Golang For Loop Over Slice

A slice is a dynamically-sized sequence of elements of the same type in Golang. To loop through a slice, we can use the range keyword, just like we did with arrays. Here’s an example:

package main

import "fmt"

func main() {
    slice := []int{1, 2, 3}
    for i, v := range slice {
        fmt.Println("Index:", i, "Value:", v)
    }
}

In this example, we define a slice of length 3, initialize it with values 1, 2, and 3, and then use the for i, v := range slice loop to loop through the slice. As with arrays, i represents the index of the current element, and v represents the value of the current element.

For Loop Over Maps in Go

In Golang, maps are used to store key-value pairs. They are one of the most commonly used data structures in Golang. To iterate over a map in Golang, we use the for range loop.

package main

import "fmt"

func main() {
    m := map[string]int{"apple": 1, "banana": 2, "orange": 3}

    for k, v := range m {
        fmt.Println(k, v)
    }
}

In this example, we define a map m with string keys and integer values. We then use the for range loop to iterate over the map and print each key-value pair. The k variable holds the key of the current iteration, and the v variable holds the corresponding value.

The order of iteration over a map in Golang is not guaranteed, and it can vary from one execution to another. The for range loop iterates over the map in an arbitrary order. If we need to iterate over the map in a specific order, we can sort the keys first and then iterate over them.

Delete a value from the map during iteration

To delete a key-value pair from a map during iteration, we need to use a separate loop or a temporary slice to hold the keys that need to be deleted.

package main

import "fmt"

func main() {
    m := map[string]int{"apple": 1, "banana": 2, "orange": 3}

    for k, v := range m {
        if v == 2 {
            delete(m, k)
        }
    }

    fmt.Println(m)
}

In this example, we iterate over the map and delete the key-value pair with the value of 2. We cannot delete the key-value pair during iteration because it will cause a runtime error. Instead, we use the delete function to delete the key-value pair after the loop has been completed.

Check key exists in Golang Map

To check if a key exists in a map, we can use the _, ok := m[key] syntax. The _ is a blank identifier that discards the value of the key if it exists. The ok variable is a boolean value that indicates whether the key exists in the map or not.

package main

import "fmt"

func main() {
    m := map[string]int{"apple": 1, "banana": 2, "orange": 3}

    if _, ok := m["apple"]; ok {
        fmt.Println("apple exists")
    }

    if _, ok := m["pear"]; !ok {
        fmt.Println("pear does not exist")
    }
}

In this example, we use the _, ok := m[key] syntax to check if the keys “apple” and “pear” exist in the map m. The first if statement prints “apple exists” because the key “apple” exists in the map. The second if statement prints “pear does not exist” because the key “pear” does not exist on the map.

For Loop a Channel in Golang

Golang also provides a powerful mechanism called channels that allows communication between goroutines (lightweight threads of execution). Channels enable a program to exchange data between different goroutines without the need for explicit locks or other synchronization primitives.

To iterate over a channel in Golang, we can use a for loop with the range keyword.

package main

import "fmt"

func main() {
    ch := make(chan int)

    go func() {
        for i := 0; i < 5; i++ {
            ch <- i
        }
        close(ch)
    }()

    for val := range ch {
        fmt.Println(val)
    }
}

In this example, we create a channel of type int and launch a goroutine that sends five values to the channel using the ch <- i statement. After sending the five values, we close the channel using the close(ch) statement.

We then use a for loop with the range keyword to iterate over the channel and print the values. The range keyword automatically reads from the channel until it is closed, so the loop will exit after reading all the values from the channel.

Loop Buffered Channels In Go

we can also create buffered channels that allow sending and receiving multiple values without blocking.

package main

import "fmt"

func main() {
    ch := make(chan int, 3)

    go func() {
        ch <- 1
        ch <- 2
        ch <- 3
        close(ch)
    }()

    for val := range ch {
        fmt.Println(val)
    }
}

In this example, we create a buffered channel with a capacity of 3 using make(chan int, 3). We then launch a goroutine that sends three values to the channel using ch <- i. After sending the three values, we close the channel using close(ch).

We then use a for loop with the range keyword to iterate over the channel and print the values. Since the channel is buffered, sending the three values does not block the goroutine, and the loop can iterate over the values immediately.

Loop over a Struct in Golang

A struct is a user-defined composite data type that groups together zero or more values of different types into a single entity.

To iterate over a struct in Golang, we need to use the range keyword with the for loop.

package main

import "fmt"

type person struct {
    name string
    age  int
}

func main() {
    p := person{name: "John", age: 30}

    for key, value := range p {
        fmt.Println(key, value)
    }
}

In this example, we use the range keyword with the for loop to iterate over the person struct instance p. The loop iterates over the struct fields and assigns each field’s key and value to the variables key and value, respectively. We then print out the key and value pairs.

Note that the order in which the fields are printed is not guaranteed in Golang, so the output of this example may vary from run to run.

Nested Struct For Loop in Golang

Golang also supports nested struct types, and we can use loops to iterate over the fields of the nested structs.

package main

import "fmt"

type address struct {
    street  string
    city    string
    country string
}

type person struct {
    name    string
    age     int
    address address
}

func main() {
    p := person{
        name: "John",
        age:  30,
        address: address{
            street:  "123 Main St",
            city:    "New York",
            country: "USA",
        },
    }

    for key, value := range p {
        fmt.Println(key, value)
    }

    for key, value := range p.address {
        fmt.Println(key, value)
    }
}

In this example, we define a person struct with a nested address struct. We create an instance of the person struct and initialize its fields with values. We then use two separate for loops to iterate over the person struct and the nested address struct. Note that we can access the fields of the nested struct by using the dot notation with the parent struct’s field.

Wrapping Up

In this blog, we explored Golang loops and their types, including the for loop, while loop, and do-while loop. We also discussed the syntax and usage of each type of loop and provided examples and outputs to help you better understand how to use them in your Golang programs.

We also explored some advanced concepts related to Golang loops, such as using break and continue statements, using labels, and using defer statements in loops. These concepts can help you write more efficient and readable code and improve your programming skills.

Remember, when writing code, it’s essential to follow best practices and optimize your code for performance and readability. Using loops effectively is one way to achieve these goals, but it’s just one part of writing high-quality Golang code.

By understanding the concepts discussed in this blog and applying them in your Golang projects, you can write more efficient and readable code and become a more skilled Golang programmer.

Reference

Was This Article Helpful?

Leave a Reply

Your email address will not be published. Required fields are marked *