Learn Go (Part-2)

Learn Go (Part-2)

Hey there!

This blog is a continuation of the Learn Go series of my Go learnings. If you want to check out the part-1 then follow this link https://mohanj.hashnode.dev/learn-go

Topics to be covered

Composite types

  • Array

  • Slice

  • Map

  • Struct

Note: The above types if tried to explain in detail each one itself would make up an entire blog. So this blog is more like a gist of those types.

Array

An array is a data structure which can hold more than just one element. For example, if you try to assign some value like 100 to some variable (var num int = 100), the variable can only hold one value 100 at a given time. But if we want to hold more than just one element like var num int = 100, 200 , it raises an error. For this kind of functionality, we can use an array.

var arr [size]type = [size]type{elements}

package main 
import "fmt"

func main(){
    var someArray [2]int = [2]int{100,200}
    fmt.Println(someArray)  // prints [100 200]
}

The declaration var someArray [2]int = [2]int{100,200} means create a variable called someArray that should be of type array [] with type as int and size of 2 elements, and store values 100, 200 in it.

As mentioned in the previous blog, we can eliminate using the var keyword and type declaration when declaring variables in a function. So the above array declaration can also be written as someArray := [2]int{100,200}.

Accessing Array Elements:

To access elements in an array we use something called Indexing. For example to access 1st element from someArray := [2]int{100,200} which is 100 we use something like someArray[0]. You may wonder why not [1] to access 1st element. This is because Indexing starts from 0. So to access second elements we would go like someArray[1].

The concept of indexing is not new. Just like in books, where there would be an index page which refers to the topic and its respective location(page number), the same goes with arrays. It just so happens that indexing starts from 0 in arrays.

package main 
import "fmt"

func main(){
    someArray := [5]int{100,200,300,400,500}
    //   0    1    2    3    4
    // [100, 200, 300, 400, 500]
    fmt.Println(someArray[0])  // prints 100 
    fmt.Println(someArray[1])  // prints 200
    fmt.Println(someArray[2])  // prints 300
}
  • As mentioned, arrays require us to mention their size(number of elements to store) when declaring the array variable, which limits us to storing more elements than its declared size.

Learn more about arrays here https://mohanj.hashnode.dev/golang-arrays

Slice

The drawback of arrays which prevents us from storing more elements than their defined size can be overcome by Slice. Slice is an array but its size is dynamic i.e it can grow its capacity when needed.

package main 
import "fmt"

func main(){
    var someArray = []int{100,200}
    fmt.Println(someArray[0])  // prints 100 
}

As you noticed, we didn't mention the size []int{100,200}, and that makes the variable someArray a slice rather than an array.

If we dig deep, slice refers to a hidden array. I'll try to make a blog explaining all those details, but for now, just know it.

Built-in Methods:

There are a few built-in methods that we can use to perform actions or to know information regarding array/slice.

  • len() -> returns the size(number of elements exists so far)

  • cap() -> returns the capacity(maximum number of elements it can hold)

  • append() -> adds new elements to slice

Note: append() method only works for slice but not array, whereas len() and cap() work for both array and slice

package main 
import "fmt"

func main(){
    var someArray = []int{100,200}  // a slice 
    fmt.Println(someArray)       // prints [100 200]
    fmt.Println(len(someArray))  // prints 2
    fmt.Println(cap(someArray))  // prints 2 
    someArray = append(someArray, 300)  // adds 300 to someArray
    fmt.Println(someArray)       // prints [100 200 300]
}

Learn in-depth about slices here https://mohanj.hashnode.dev/golang-slices

Map

Map is yet another powerful data structure. Imagine if we met a scenario where we need to store elements with some name to it in an array, like arr := [2]int{"first":100, "second":200}, it doesn't work, as arrays are just meant to store values only. Maps exactly do this. It allows us to store elements with some name to it, known as a key so that whenever we want an element we could directly access that element with its associated key, just like we would access array elements with their index.

var someMap map[type]type = map[type]type{elements}

The perfect example of the usage of map data structure is our mobile contact list, where each name is associated with some mobile number. John: 4252029421. Here the name John is called key and 4252029421 is the associated value to that key.

package main
import "fmt"

func main(){
    var someMap = map[string]int{"John":4252029421}
    someMap["Steve"] = 8763451204
    fmt.Println(someMap["John"])   // prints 4252029421
    fmt.Println(someMap["Steve"])  // prints 8763451204
}

Here we can use any data type for key and value like key could be int and value could also be int. An important note is, the key should always be unique. We can't have duplicate keys in maps.

package main
import "fmt"

func main(){
    var someMap = map[string]int{"John":4252029421, "John":6541237861}
    fmt.Println(someMap["John"]) // raises error duplicate key
}

In the above example even though the values for key John is different, being the same key John, creates ambiguity. So no duplicate keys.

Struct

Struct is to create custom data types. Basically used to combine more than one data type. If you ever want to create a data type of your own with the existing basic types like string, int, float, bool, etc. We can do so by struct (short for structure).

type structName struct {

date fields...

}

package main

import "fmt"

type customStruct struct {
    Name string
    Age  int
}

func main() {
    var details = customStruct{Name: "John", Age: 25}
    fmt.Println(details)      // prints {John 25}

    var details2 customStruct
    details2.Name = "Robert"
    details2.Age = 32
    fmt.Println(details2.Name) // prints Robert
}

In the above code, we have defined a customStruct with data fields as Name and age with string and int as data types respectively.

In the main function, I've initialized a variable called details with customStruct{Name:"John", age:25}, assigning values to both Name and age fields with "John" and 25 respectively.

The second variable details2 is just to show you that we can assign values using dot notation. We can access each field with dot notation.

We can even create functions and bind them to this custom struct. That'll be for another blog, till then, peace out!