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:
- 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 aforstatement 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.
- Init statement: Code that is executed be the first iteration
- Condition expression: checked/evaluated before every iteration
- 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.
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 defineUser structtype 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
thereflect packagein order to access the keys and values of a Go
struct. We then initialize a variable namedvaluesthat holds the
value from the user instance usingreflect.ValueOf(u).
TheValueOfmethod returns a Value representing the run-time data. In
the next line, use the callType()method on thevaluesrun 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).Nameand
values.Field(i).Interface()respectively.typesOf.Field(i).Namereturns
the keys names likeFirstName,LastName,EmailandPhone
respectively whilevalues.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
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 usefmt.Printf()method from thefmt 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
In the above example, we format our unicode integer in the loop from the
previous example using%cplaceholder. 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 typeint,stringandfloat. We then use
thefor rangeloop 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.
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 calledtestChannel()that
takes a channel of type string as an argument. ThetestChannel()
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 calltestChannel()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.
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.


