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.