Structs and Maps in GOlang

This is the third article in the “Getting Started with GOlang” series. If you have not checked out the previous article please check it out before diving into this. 1. Getting started with GOlang 2. Slices, Custom Types and Receiver Functions(methods) in GOlang 3. Structs and Maps in GOlang 4. Pointers and Passby value/reference in GOlang 5. Interfaces in GOlang
STRUCTS
Structs are a typed collection of fields. Basically, a group of information is grouped together as a type, which can be used to create instances of the struct we defined. These are similar to objects in JavaScript, it's just that these need separate type declarations before we can create its instance.
Let me give you a scenario where we could use structs. So, let's say, we are collecting information of students. Now, every time we need to create a new student, we need to declare new variables for first name, last name, address, etc, and they cannot be the same so we probably could use something like peter-name, peter-address, etc. Instead, with structs, we can simply define a type of struct that contains keys like firstName, Address,… which contain respective values. Then we instantiate the struct variable with just the student's name.
Now, create a new directory, and name it structs if you want to. Create a new file main.go and add the following code to it.
package mainimport "fmt"type student struct {
firstName string
lastName string
}func main() {Peter := student{firstName: "Peter", lastName: "Parker"}Peter.print()
}func (s student) print() {
fmt.Println("First Name: ", s.firstName, " Last Name: ", s.lastName)
}Now, you can go ahead and run the above code with, go run main.go. You should see something like:
First Name: Peter Last Name: ParkerSo, let's dive to the code, initially we define a struct named student with type student struct{} . Inside the parenthesis, we add all the names of keys and the types we want inside our struct. And remember this is just the definition of a type inside our program which is a struct.
Now, we need to initialize a variable with this struct. This is similar to other variable initialization and can be done in multiple ways. You can initialize the instance of the struct and assign values at the same time or use keys to assign the values later as shown below:
var peter student
peter.firstName = "Peter"
peter.lastName = "Parker"We can access the values inside the struct instance with the key we defined while defining our struct type.
After that, We create a “receiver function” name print(). Which then we call right after its declaration and use a print function to print different values inside our struct instance peter.
Also, we can nest a struct inside another struct. So, let's create another struct named contact.
type contact struct {
email string
phone int
}Now, add another line inside the type definition of struct such that it becomes:
type student struct {
firstName string
lastName string
contactInfo contact
}Here, we added a third key contactInfo of type contact. Now, there is another simple trick that we could for efficiency. If the name of the key and type of the struct are the same, then we can just write it once. So, changing the key contactInfo to just contact, we could simply write:
type student struct {
firstName string
lastName string
contact
}Now, Change the instance peter to also add the contact data while initialization.
Peter := student{
firstName: "Peter",
lastName: "Parker",
contact: contact{
email: "[email protected]",
phone: 9874563210,
},
}Notice the pattern, to assign value inside the contact struct we need to define another struct of type contact, hence the keyword contact. We can use multiple lines while defining the structs, but doing so. We need to add a “comma” after every value we assigned, even the last one.
There is another print function that helps visualize a struct better. Replace the print() function with the following:
func (s student) print() {
fmt.Printf("%+v", s)
}Run the program and you should see something like this in your terminal.
{firstName:Peter lastName:Parker contact:{email:[email protected] phone:9874563210}}Now, to access the nested values we simply chain the keys. As for our above case, if we need to access just the email of peter, we write peter.contact.email
MAPS
Maps are similar to structs in the way that, they too hold a collection of values as key-value pairs. But there is a fair number of differences.
Firstly, all the keys and all the values inside a Map are defined when it is initialized and stay the same for all the key-value pairs. For example, if we initialize a map with a key of type string and value of type int, all the keys need to be of type string and values of type int.
Secondly, we can iterate over Maps with a loop, we cannot with Structs.
Also, Maps are Pointer types while structs are Value types. We will discuss more of these in the next article.
Now, create a new directory, name if map if you want, create a file main.go and put the following code inside it.
package mainimport "fmt"func main() {colors := map[string]string{
"red": "#ff0000",
"green": "#00ff00",
}
colors["white"] = "#FFFFFF"printMap(colors)
}func printMap(c map[string]string) {
for color, hex := range c {
fmt.Println("Hex code for ", color, " is ", hex)
}
}Run the program, and you should see something like:
Hex code for red is #ff0000
Hex code for green is #00ff00
Hex code for white is #FFFFFFHere, we initialize a map with both key and value as type string, using map[string]string{}. And inside the parenthesis, we add the necessary values.
We can also assign values later, to the same key or a different key using the syntax like colors[“white”] = “#FFFFFF”
That is basically how maps are used. Any kind of type could be used to represent the values, inside a map. The interesting part, however, is going on inside the printMap() function. Here, using the for range key as we used for iterating over a slice in our previous article, we can iterate over a map, and instead of the index in a slice, we receive the key as the first return. And the second return is the value similar to the slice. This iterating property of the map makes it very useful for bundling similar data and operating similar actions in a loop with those data. For your own exercise, you can create a map of the struct student we created in the first half of the article and loop over that map. This should show you how interesting and useful maps and structs are.
Hope. This you find this useful. My next article will be about Pointer and value types in go which is a bit to handle at first, but you’ll feel much control over your coding with these concepts with you. Feel free to question anything that I missed or misunderstood. Happy Coding :)
