Go - Use-cases of non-primitive datatypes

vchiranjeeviak

Chiranjeevi Tirunagari

Posted on September 21, 2022

Go - Use-cases of non-primitive datatypes

Introduction

Welcome to the part 7 of Go series. In the previous part (part 6): https://dev.to/vchiranjeeviak/go-maps-structs-485c, we saw what Maps and Structs are and how different operations like creating, adding, deleting etc can be done on them. In this one, lets see how we can iterate through them and the use-cases of these non-primitive datatypes.

Iterating through non-primitive datatypes

Arrays, Slices and Maps are some sort of collection of some similar type of values. There might be many situation where we want to go through each of these collections, do some computation or update the values. No matter what we do, going through the entire collection is the point to note here. We use loops to do this. Revisit this https://dev.to/vchiranjeeviak/go-conditionals-and-loops-5f1g loops article if haven't already for more context on loops.

Using normal for loop to iterate

Run a "for" loop from 0 until length of collection and do any operation on each item inside collection using index operator.

Program to print all items in a slice in new line

package main

import "fmt"

func main() {
    arr := []string{"one", "two", "three", "four"}

    for i := 0; i < len(arr); i++ {
        fmt.Println(arr[i])
    }
}
Enter fullscreen mode Exit fullscreen mode

Output:

Output1

We can iterate through an array in the similar way. But in case of maps, this way of iteration is possible only if the keys in the map are of the int type. If it is not of int type, we can't use integer indices inside index operator.

Program to add all items in an array

package main

import "fmt"

func main() {
    arr := [5]int{1, 2, 3, 4, 5}
    sum := 0
    for i := 0; i < len(arr); i++ {
        sum = sum + arr[i]
    }
    fmt.Println("Sum = ", sum)
}
Enter fullscreen mode Exit fullscreen mode

Output:

Output2

Using for-each loop to iterate

We now know why iterating using normal "for" loop is not always possible in case of maps. It is because maps don't guarantee that they always have int keys and while iterating using a normal "for" loop give us only integer value.

for-each loop lets us overcome this issue. If we use for-each loop with array or slice, it gives us 2 values, which are position and value. If we use for-each loop with maps, it gives us 2 values again, which are key and value.

The syntax to use it is for <pos/key>, <value> := range collection { }.

Program to print key and value combined as a string in a string-string map

package main

import "fmt"

func main() {
    mapp := make(map[string]string)
    mapp["one"] = "1"
    mapp["two"] = "2"
    mapp["three"] = "3"

    for key, value := range mapp {
        fmt.Println(key + value)
    }
}
Enter fullscreen mode Exit fullscreen mode

Output:

Output3

Program to print position and value in a slice side by side

package main

import "fmt"

func main() {
    arr := []int{23, 52, 745, 13}

    for pos, val := range arr {
        fmt.Printf("%v -> %v \n", pos, val)
    }
}
Enter fullscreen mode Exit fullscreen mode

Output:

Output4

This is how we can iterate through any collection like arrays, slices and maps.

Real world scenarios where non-primitive datatypes are useful

  • When we want to keep track of some items as a collection and we know the upper limit of the number of these items or want to limit the items to a particular number, then arrays are useful. I know it almost feels like a definition. Let's say we are keeping track of students joining in a class. Obviously every class is limited and let's consider the limit as 60. To store names/numbers of these students, we will need an array of max size 60.

  • Now, consider this situation where we need to keep track of voters in a country like we did for students in above example. Number of voters is not limited and not constant. So, we can't keep a cap on the value. This is a situation where we need a slice. When there is no limit required or known, to store items as a collection, slice is the way to go.

  • We can use maps wherever we are connecting two entities as a whole item. But the condition is that at least one of the two entities should be unique among all items. The unique entity is called as key. An item can be uniquely identified by these keys. A real world case can be keeping track of credit card number along with user name. Here, the relation we chose is the credit card and it's owner. So, credit card number is the key and owner name is the value. We can't represent a relation of a person and his credit cards. It is because, a person name can't be unique for all items. But in first case, a credit card number will always be unique in any pair.

A complex example of non-primitive datatypes and iteration

import "fmt"

type person struct { // defining a struct
    name string
    city string
}

func main() {
    register := make(map[int]person) // map of int key and person value type
    register[5463715] = person{name: "Ram", city: "Ayodhya"}
    register[2385928] = person{name: "Sita", city: "Mithila"}
    register[1432545] = person{name: "chiranjeevi", city: "Bangalore"}

    for id, person := range register {
        fmt.Printf("%v having id %v lives in %v. \n", person.name, id, person.city)
    }
}
Enter fullscreen mode Exit fullscreen mode

Output:

Output5

Conclusion

That's it for this one. In the next one, we will see what defer, panic, recover are. Let's meet there.

More on Go lang will be coming soon and do follow me to see them. Make sure you like and share if you felt this good.

Let's connect on: Twitter LinkedIn Showwcase

💖 💪 🙅 🚩
vchiranjeeviak
Chiranjeevi Tirunagari

Posted on September 21, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Go - Maps and Structs
go Go - Maps and Structs

September 7, 2022