Golang for loop with Struct, Maps, Strings, Interfaces, Channels

Getting started with golang for loop

A loop in programming is a sequence of instructions that repeats itself until a certain condition is met. In this tutorial we will learn about Go For Loop through different data structures like structs, range , map, array, slice , string and channels and infinite loops. In Go, for loop is the only one contract for looping.

In this tutorial we will cover following scenarios using golang for loop:

Advertisement
  • Looping through Maps
  • Looping through slices.
  • Looping through strings
  • Looping through interface
  • Looping through Channels
  • Infinite loop

 

Syntax for using for loop in GO

In Go, this is what a for statement looks like:

for (init; condition; post) {
}

In Go, the for loop is the only construct for looping. The basic for loop in Go has the following components that are separated by semicolons.

  1. Init statement: Code that is executed be the first iteration
  2. Condition expression: checked/evaluated before every iteration
  3. Post statement: executed at the end of the iteration

The prerequisite to follow up with this article is to install Go runtime if you haven't already and create a main.go file in your working directory.

Example

package main
 
import (
   "fmt"
)
func main() {
   total := 0
   for i := 0; i < 10; i++ {
       total += i
   }
   fmt.Println(total)
}

Output

$ go run main.go
45

 

Using golang for loop with struct

To loop through struct types in Go , makes use of the reflect package. The Reflect package implements run-time reflection, hence allowing a program to modify objects with arbitrary  types.

Advertisement

Example

package main
 
import (
   "fmt"
   "reflect"
)
 
type User struct {
   FirstName string
   Lastname  string
   Email     string
   Phone     int
}
 
func main() {
   u := User{
       FirstName: "John",
       Lastname:  "Doe",
       Email:     "johndoe@gmail.com",
       Phone:     1234567,
   }
   values := reflect.ValueOf(u)
   typesOf := values.Type()
   for i := 0; i < values.NumField(); i++ {
       fmt.Printf("Field: %s\tValue: %v\n", typesOf.Field(i).Name, values.Field(i).Interface())
   }

Explanation

In the above example, we define User struct type with several attributes. In the main function, we then create an instance of the User struct.  Unlike other types like Go maps that allow us to loop through keys and values on the fly, Go requires that you use the reflect package in order to access the keys and values of a Go struct. We then initialize a variable named values that holds the value from the user  instance using reflect.ValueOf(u) . The ValueOf method returns a Value representing the run-time data. In the next line, use the call Type() method on the values run time data.In order to loop through all the keys and values in the user object, we get the number of key-value pairs from the user object using . Using for loop, we loop through the size of the values and access each key and value by calling typesOf.Field(i).Name and values.Field(i).Interface()  respectively. typesOf.Field(i).Name  returns the keys names like FirstName , LastName , Email and Phone respectively while values.Field(i).Interface()  returns the respective values of the keys.

Output

$ go run main.go
Field: FirstName        Value: John
Field: Lastname Value: Doe
Field: Email    Value: johndoe@gmail.com
Field: Phone    Value: 1234567

 

Using golang for loop with Maps

Go maps are one of the useful data structures and in computer science at large. It is made up of key and value where key can be any type that is comparable and a value that can be any type. Another map feature is that its unordered collection and it can order preserve the of the keys. We will loop through maps using the for-range type of Go for loop.

package main
 
import "fmt"
 
func main() {
   user := map[string]interface{}{
       "FirstName": "John Doe",
       "LastName":  "Doe",
       "Country":   "Go Land",
       "Email":     "johndoe@golinuxcloud.com",
   }
 
   for key, value := range user {
       fmt.Printf("Key: %s === Value: %s \n", key, value)
   }
}

Explanation

The range form of the for loop is used to iterate over maps and slices. When looping through the user map, two values are returned after every iteration. The first value is the key and the second value is the value for the respective key.

Output

$ go run main.go
Key: FirstName === Value: John Doe
Key: LastName === Value: Doe
Key: Country === Value: Go Land
Key: Email === Value: johndoe@golinuxcloud.com

 

Using golang for loop with slices

A slice in a Go is an array without a fixed size. It is important to note that a slice sits on a type of an array and therefore it does not store any data , rather it describes a section of an underlying array. To successfully loop through a Go slice, use the for range form of the Go for loop as shown below.

package main
 
import "fmt"
 
func main() {
   nums := []int{1, 2, 3, 4, 5}
 
   for index, value := range nums {
       fmt.Printf("Position : %d == %d \n", index, value)
   }
}

Output

$ go run main.go
Position : 0 == 1
Position : 1 == 2
Position : 2 == 3
Position : 3 == 4
Position : 4 == 5

 

Using golang for loop with strings

A string is a sequence of characters. For example “GolinuxCloud.com” is a string of characters . The Go for-range form loop can be used to loop through strings.

Example

Advertisement
package main
 
import "fmt"
 
func main() {
   greetings := "Hello!"
 
   for _, char := range greetings {
       fmt.Printf("%c \n", char)
   }
}

Explanation

Looping through a string in Go with the range keyword returns the index of each character and the respective unicode(char) integer of each character in the string.

Output

$ go run main.go
0 ==> 72
1 ==> 101
2 ==> 108
3 ==> 108
4 ==> 111
5 ==> 33

 

In order to print out the actual character values instead of unicode value, we can use fmt.Printf() method from the fmt package , that allows us to convert values from on type to another type, in our case, it will be from unicode to string.

Example

package main
 
import "fmt"
 
func main() {
   greetings := "Hello!"
 
   for _, char := range greetings {
       fmt.Printf("==> %c \n", char)
   }
}

Explanation

Advertisement

In the above example, we format our unicode integer in the loop from the previous example using %c placeholder.  We also used _ to indicate to the for loop body that we really don't care about the index value.

Output

$ go run main.go
==> H
==> e
==> l
==> l
==> o
==> !

 

Using golang for loop with interfaces

In Go every type implements an empty interface. An empty interface is an interface without any methods. Empty interfaces enables developers to create slices made up of different types as shown in example below.

Example

package main
 
import (
   "fmt"
)
 
func main() {
   items := []interface{}{1, "hello", 3.14}
   for _, item := range items {
       switch item.(type) {
       case int:
           fmt.Println("int")
       case string:
           fmt.Println("string")
       case float64:
           fmt.Println("float64")
       default:
           fmt.Println("unknown")
       }
   }
}

Explanation

In the preceding example, we create a slice of interface type and add values of type int ,string and float . We then use the for range loop to loop through the items. We ignore the indexes of the values by using the underscore (_) to tell Go we do not really care about the index. Using a switch statement we check the type of each item in the slice and print a message on the terminal based on the type.

Advertisement

Output

$ go run main.go
int
string
float64

 

Using golang for loop with Channels

Channels are conduit pipes that connect concurrent goroutines. In Go, channels are typed pipes that developers can send and receive values using the <- operator. The values in the channel flow in the direction the arrow points to.  We can use a for loop with channels to repeatedly send values  from the sender to the receiver. It is important to note that the sender of values can close a channel to indicate that no more values will be sent and this marks the end of the loop.

Therefore , using a range loop, the channel will receive values repeatedly until the channel is closed. It is only the sender that is allowed to close the channel and any attempt to send on a closed channel will result in a panic.

Example

package main
 
func testChannel(c chan string) {
   users := []string{"user1", "user2", "user3", "user4", "user5"}
   for _, user := range users {
       c <- user
   }
   close(c)
}
 
func main() {
   c := make(chan string, 10)
   go testChannel(c)
   for i := range c {
       println(i)
   }
}

Explanation

In the above example, we define a function called testChannel() that takes a channel of type string as an argument. The testChannel() function loops through an array of strings using the for range loop and sends the string to the channel. The operator <- has been used to send messages in the direction of the channel. After all strings have been sent into the channel, the channel is closed. In the main function, we initialize a channel of type string. This channel will be used to pull string values from it. We then call testChannel() to start sending string values into the channel. After filling the channel with string values , we use for range loop again to pull messages of the channel one after the other and print the string values in the terminal as shown in the below output.

Advertisement

Output

$ go run main.go
user1
user2
user3
user4
user5

 

Create and Infinite for loop

Go has an easy way of defining an infinite loop. In most cases we use infinite loops to run until an external intervention occurs. Please note that infinite loops do not have a stopping condition and therefore should always be used with a lot of care.

Example

package main
 
import (
   "fmt"
   "time"
)
 
func main() {
   for {
       fmt.Println("https://www.golinuxcloud.com is the best Go resource for learning Go")
       time.Sleep(2 * time.Second)
   }
}

Explanation

In the above code sample, the code will run indefinitely until we stop it by pressing ctrl + C on the keyboard as indicated in the output below.

Output

$ go run main.go
https://www.golinuxcloud.com is the best Go resource for learning Go
https://www.golinuxcloud.com is the best Go resource for learning Go
https://www.golinuxcloud.com is the best Go resource for learning Go
^Csignal: interrupt

 

Summary

In this article ,we learn about looping through different data structures like structs, strings, maps, slices and channels. Go struct is the only data structure that requires an extra package called reflect to be able to loop through both keys and values. The other data structures do not require any package to be able to loop through their items and attributes.

 

References

golang flow control
golang for loop

 

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment

X