# Introduction

> Go is an open-source programming language that makes it easy to build simple, reliable, and efficient software. - Excerpts from Golang.org

## Why need Go

### Computers Evolved but programming languages haven't

Intelligent machines have evolved. Today we see a plethora of intelligent machines; be it computers, mobile devices, IoT devices; interacting with web apps, services and platforms. These intelligent machines come in different shapes, sizes and varying capabilities; be it Android/iOS powered machines of different screen sizes, resolutions, CPU cores and memory. But when it comes to programming languages and tools out there; there is still a lot to cover; to keep up with the evolutions of machines. For example, there are a bunch of programming languages and tools that still can not leverage all CPU cores at once. Forget about concurrent programs even achieving parallelism is tough using existing tools.

In addition to capabilities as explained, we also have developers who love to curate efficient products and organizations want to go to market early to cash in this cut-throat competition. Hence this world needed technology or tool that is simple to curate, fast to prototype, easy to understand, internet aware yet have complex abstraction to leverage capabilities of intelligent machines out there. And this is where **Golang** comes into the picture

### Choice: Rapid Development or Performance

As a software curator, one has always faced a dilemma while choosing the tech stack to develop software. Given the combinations of technology available, one can either choose rapid development or Performance.

If one does choose Rapid development to hit the market early, they need to make choices again to improve performance if their software becomes widely used. Take an example of [Twitter](https://twitter.com), early on they used Ruby and Rails for rapid development but after growth, they had to rethink their technology stack

### Need to scale on the go

As explained earlier; with existing bunch of technologies if one goes for rapid development, the performance had to be forgone or to get performance; rapid development is a thing not known. For example, C is the technology that could be made to leverage all CPU cores, but it is neither suited for rapid development nor easy to manage the line of codes that are required to develop complex software that exists today

Similarly, if one chooses Ruby or NodeJS, rapid development can be done but performance is something farfetched for complex projects

### Built in Concurrency (Go routines/channels)

Golang is developed while keeping the challenges in developing software in the 21st century. While it allows one to leverage complex underlying hardware architecture, at the same time has enough high-level abstraction needed for rapid development.

Golang has inbuilt goroutines, that are lightweight, self-contained and scheduled by go itself to achieve parallelism, leveraging all available cores and at the same times channels make them concurrent while sharing data and states among them as and when required

### Composition over Inheritance

Many of us have already been worked on some kind of technology using OOPs concept and are familiar with Inheritance. Go does not support inheritance while it does implement composition. So what's the difference?, one asks.

Composition is something smaller parts, that when put together makes a big part of that. To understand the difference lets take an example. A vehicle is a generic class that can have attributes like fuel, engine, tires and behavior like start, stop, accelerate. And this can be inherited into Car's definition since the car would have all the properties it has and adds some more, that makes it a car.

While in composition, one creates a component that when put together makes a thing. For example tires, engines are components, they can be used in car, trucks and pickup alike. That's the difference

Components may not be much better than inheritance, both have there pros and cons. But one thing an experienced programmer understands is that components are tiny parts; that make it easier to maintain and reuse. Components are also not bound to a particular definition like tires are not just to be used in vehicle always, they have other uses as well. In inheritance one puts a generic framework that makes it hard to use for things that do not fall well in that framework definition, while components are like, libraries/modules, one can fit these into anything and they would make there properties and behavior available.

Another difference is, in Inheritence child class knows what class it is inheriting from, but child component never knows whom it is providing there services to. That's when thought well, makes it decoupled and in programming its a good thing.

### Modern, Fast and comes with a powerful set of standard libraries

Open source has always been on the rage, one would find a plethora of solutions out there that would add to existing technologies to leverage something that was either not available when technology was implemented not meant for that

With this comes a lot of libraries/extensions/plugins that add to confusion of developers, sometimes are not well thought or implemented. This makes it risky using third party libraries and plugins

So when go was being written, authors have a very well thought out plan for making all heavily used components/features as part of standard libraries (e.g `net-http`)


# Installation

## Getting Super Powers

Installing Go is easy, one can visit their [download](https://golang.org/dl/) page and download the latest version build for there respective Operating System.

Here are some popular one

### Mac OSX

One could use homebrew distribution by running following command in terminal

```bash
brew install go
```

This would automatically take care of all the things needed for installation. Alternatively, [here](https://dl.google.com/go/go1.14.2.darwin-amd64.pkg) is a direct link for download for OSX

{% hint style="warning" %}
Note: Direct link points to Go v1.14.2 at the time of writing this book. This may be periodically updated, but one is requested not to depend on it for the latest version
{% endhint %}

### Ubuntu 18.04 or higher

Again it is highly recommended that one should install the Golang directly from [download](https://golang.org/dl/) page, or by a direct link [here](https://dl.google.com/go/go1.14.2.linux-amd64.tar.gz)

{% hint style="warning" %}
Note: Direct link points to Go v1.14.2 at the time of writing this book. This may be periodically updated, but one is requested not to depend on it for the latest version
{% endhint %}

Once you have downloaded the `gzip` file, extract it someplace in your home directory and then add following lines to you `$HOME/.bashrc` or `$HOME/.bash_profile` file

```bash
export GOROOT=$HOME/bin/go1.14.2.linux-amd64/go
export PATH=$PATH:$GOROOT/bin
export GOPATH=$HOME/code/gocode
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOBIN
```

{% hint style="info" %}
Please replace path with the path you have extracted the zip file into
{% endhint %}

Here `GOROOT` points to the parent directory of bin in go folder, then the bin path is extended to `PATH` variable. `GOPATH` is where you go get or personal code lives, `GOBIN`points to go package or local code binary that gets generated when go code is compiled. We will discuss these at length, later

Or alternatively, If you're using Ubuntu 18.04 LTS or 19.10 on amd64, arm64, armhf or i386, then you can use the `longsleep/golang-backports` PPA and install Go 1.14.

```bash
sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
sudo apt install golang-go
```

{% hint style="warning" %}
Note *\*\**&#x74;hat `golang-go` installs the latest Go as default Go. If you do not want that, install `golang-1.14` instead and use the binaries from `/usr/lib/go-1.14/bin`

These packages were not created by the Go project, and we don't support them, but they may be useful for you.
{% endhint %}

### Windows

For Microsoft Windows, it is highly recommended that one should install from Golang [download](https://dl.google.com/go/go1.14.2.windows-amd64.msi) page

## Instructions

[Official binary distributions](https://golang.org/dl/) are available for the FreeBSD (release 10-STABLE and above), Linux, macOS (10.11 and above), and Windows operating systems and the 32-bit (`386`) and 64-bit (`amd64`) x86 processor architectures.

If a binary distribution is not available for your combination of operating system and architecture, try [installing from source](https://golang.org/doc/install/source) or [installing gccgo instead of gc](https://golang.org/doc/install/gccgo).

## System Requirements

| Operating System                    | Architecture                           | Notes                                                                      |
| ----------------------------------- | -------------------------------------- | -------------------------------------------------------------------------- |
| FreeBSD 10.3 or higher              | amd64, i386                            | Debian GNU/kFreeBSD not supported                                          |
| Linux 2.6.23 or higher with glibc   | amd64, i386, arm arm64, s390x, ppc64le | CentOS/RHEL 5.x not supported. Install from source for other libc          |
| Mac OS 10.11 or higher              | amd64                                  | use the clang or gcc† that comes with Xcode^^ for `cgo` ^ support          |
| Windows 7, Server 2008 R2 or higher | amd64, i386                            | use MinGW (`386`) or MinGW-W64 (`amd64`) gcc^. No need for cygwin or msys. |

{% hint style="warning" %}
^ A C compiler is required only if you plan to use [cgo](https://golang.org/cmd/cgo).\
^^ You only need to install the command-line tools for [Xcode](https://developer.apple.com/Xcode/). If you have already installed Xcode 4.3+, you can install it from the Components tab of the Downloads preferences panel.
{% endhint %}

## Testing the installation

Now since we are done with installation. Let's test if everything is fine before moving forward. Fire up a terminal on your system and run following command

```bash
go version
# OUTPUT: go version go1.14.2 linux/amd64
```

If everything is fine one should see version output correctly. To test tooling run following command in terminal

```bash
gofmt -v
flag provided but not defined: -v
usage: gofmt [flags] [path ...]
  -cpuprofile string
        write cpu profile to this file
  -d    display diffs instead of rewriting files
  -e    report all errors (not just the first 10 on different lines)
  -l    list files whose formatting differs from gofmt's
  -r string
        rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')
  -s    simplify code
  -w    write result to (source) file instead of stdout
```

If you get something similar without any error. We are good to Go


# First Program

## Classic Hello World Program in Go

Okay, so we are all set up with Go. Now let's create our hands dirty and create a trivial Hello World program. Let's create a file and it `hello.go`

```go
package main
import "fmt"
func main() {
    fmt.Println("Hello World")
}
```

That's it. We are done with our program and now save it in a file named `hello.go` Now Go provides us to compile and run the program in a single command. Fire up the terminal, head in a folder where we saved `hello.go` and run

{% hint style="info" %}
Note: For example code shown here refers to go environment in Ubuntu 18.04. Illustration may change a bit depending upon OS being used
{% endhint %}

```bash
go run hello.go
# => Hello World
```

This should output the > Hello World string. Go also provides us a way to compile this program into executables by using `go build`

```bash
go build hello.go
# => This should create an executable in same directory
# => hello  hello.go
```

Is `hello` is an executable generated by `go build`. This can be run in terminal

```bash
./hello
# => Hello World
```


# Code Organisation

So before we move forward and start writing other code, lets first look deeper into how Go organizes code.

Go programs are organized into packages. A package is a collection of source files in the same directory and is compiled together. Functions, types, variables, and constants defined in one source file are visible to all other source files within the same package.

In Go, each file has to belong to a package. Remember our first program, we did mention `package main` in very first line, that means our code is packaged as main, though in Go `package main` means entry point for that program, we will discuss that later

A repository contains one or more modules. A module is a collection of related Go packages that are released together. A Go repository typically contains only one module, located at the root of the repository. A file named `go.mod` there declares the module path: the import path prefix for all packages within the module. The module contains the packages in the directory containing its `go.mod` file as well as subdirectories of that directory, up to the next subdirectory containing another `go.mod` file (if any).

Note that one doesn't need to publish your code to a remote repository before you can build it. A module can be defined locally without belonging to a repository. However, it's a good habit to organize your code as if you will publish it someday.

Each module's path not only serves as an import path prefix for its packages but also indicates where the `go` command should look to download it. For example, to download the module `golang.org/x/tools`, the `go` command would consult the repository indicated by `golang.org/x/tools`, first, it would look into $GOPATH variable directory for directory structure `golang.org/x/tools` if not then it would resolve it from `https://golang.org/x/tools`

An import path is a string used to import a package. A package's import path is its module path joined with its subdirectory within the module. For example, the module `github.com/google/go-cmp` contains a package in the directory `cmp/`. That package's import path is `github.com/google/go-cmp/cmp`.

{% hint style="info" %}
Packages in the standard library do not have a module path prefix.
{% endhint %}

`$GOPATH` is path where go will look to resolve your packages first, if not then tries to download it. `$GOBIN` is a path to a folder where when a package, module or program build will produce binaries

{% hint style="info" %}
One should already have $GOPATH and $GOBIN variable saved and pointing to directories where you would like go binaries to be saved. It would best practice to also make $GOBIN to append to $PATH so that those binaries are resolved
{% endhint %}

Let's go ahead and create our first program again, to do that let's create a directory structure that would make it easy to publish our programs

```bash
cd $GOPATH
mkdir -p src/github.com/bagwanpankaj/hello_go
cd src/github.com/bagwanpankaj/hello_go
go mod init github.com/bagwanpankaj/hello_go
#=> go: creating new go.mod: module github.com/bagwanpankaj/hello_go
```

That's it we created a go module having a module path. Now let's see what Go did

```bash
ls
#=> go.mod
cat go.mod 
module github.com/bagwanpankaj/hello_go

go 1.14
```

So now we see what go did, it just created a file `go.mod` defining import path for module and version used to create it. That's good. Now let's create a file named `hello_go.go` and copy over content from our first program

```bash
package main
import "fmt"
func main(){
  fmt.Println("Hello World")
}
```

Save an done. Now let's see with $GOPATH and $GOBIN set, what go tools can do for us. In the terminal, run following command

```bash
cd $GOPATH
go install github.com/bagwanpankaj/hello_go
```

That command gave no output, how is that :(. Okay, let's see if we have the program installed. In terminal run

```bash
hello_go
# Hello World
```

{% hint style="warning" %}
Do not panic if you do not get output, it may be because your $GOBIN is not part of the $PATH so set that up and it should work, as long as `go install` is creating bin under $GOBIN
{% endhint %}

Well where did that come from and how? Let's dive deep, so when we ran `go install`, it did compile and created a binary file, that we should find in our $GOBIN folder, let see

{% hint style="info" %}
**Note**: if $GOBIN is not set, Go will install binaries under $GOPATH/bin folder always
{% endhint %}

```bash
ls $GOBIN
hello_go
```

Well, we have it there. To our, amusement Go provides a way to set GOBIN and can be achieved via

```bash
go env -w GOBIN=/some/other/directory
```

To undo this setup one can use

```bash
go env -u GOBIN
```

{% hint style="info" %}
Windows user should read [this](https://github.com/golang/go/wiki/SettingGOPATH) to see how to set GOPATH
{% endhint %}


# Variables

Go is strictly typed language, meaning that one has to define type of the value a variable can hold. In Go, variables need to be explicitly declared and further used by the compiler to infer types and type-checking.

Let's look at an example

```go
package main
import "fmt"
func main() {
    var str = "This would be auto infered as string"
    fmt.Println(str)
    // multiple variable declaration at once 
    var one, two int = 1, 2
    fmt.Println(one, two)
    // Again type will be inferred here on first initialization
    var isHappy = true
    fmt.Println(isHappy)
    // variable is declared but not initialized
    var willHold int
    fmt.Println(willHold)
    // shorthand for declaration as well as initialization
    fruit := "oranges"
    fmt.Println(fruit)
}
```

To try the above example, I would prefer to use [Go playground](https://play.golang.org/), since these are small examples and Go playground is a perfect example. Let go and put out code in Go Playground and hit 'Run'. Here is the output

```bash
This would be auto inferred as a string
1 2
true
0
oranges
```

Now let's examine, what we did line by line. At line#4, we declared a variable while initializing it to a string, but we did not mention type. Whe type is not mentioned while declaration and initialization, Go will automatically infer type of that variable by type of the value being assigned. So in our case, `var str` will be of type `string`

But Go will complain when a variable is declared but not assigned without type declaration. Let's remove the assignment and run the program again, what does one see? Obviously an error

```go
var str
```

```go
./prog.go:4:12: syntax error: unexpected newline, expecting type
```

It complains regarding type of var str is not defined, because Go could not infer type in absence of assignment, so it needs type to be declared explicitly when a variable is not assigned any value

When a variable is declared but not assigned, then go will by default assign zero value for that type. So for string type zero value is bank string `''` , for type int its `0`

Similarly Go allows one to declare multiple variables, multiple assignments at the same time in one line, see line#7

```go
var one, two int = 1, 2
```

Here we declared a variable `one` and `two` as int and assigned 1 and 2 to them. On Line#10, Go again auto infers type by value it is being assigned. But what about Line#16?, one asks.

This `:=` is shorthand for variable declaration and assignment, this is equal to

```go
var isHappy = true
```


# Constants

Constants in Go are declared similar to variables but with `const` keyword. Constant in Go can appear anywhere variable can appear and does not have shorthand as var has. The simplest way to define a string constant would be

```go
const str = "Hey, I am defined as constant"
```

Yes, I know what you may be thinking, should the constant name not be all capital? No, in Go, it's not mandatory, constant can be all capital, came cased or usual snake cased. There are no such specific guidelines on how constants should be named

But for the sake of consistency, I would suggest that one should use camel case while naming constants. But how do constants differ from variables in Go? In Go, like any other language constants can not be reassigned. To test this hypothesis, let's run the following code in Go Playground.

```go
package main
import "fmt"
const Pi = 3.14
func main() {
    const World = "世界"
    fmt.Println("Hello", World)
    fmt.Println("Happy", Pi, "Day")
    World = "World"
}
```

The above code, when executed would error. Because constants can not be reassigned

```go
./prog.go:8:8: cannot assign to World

Go build failed.
```

All set, right? :) No

In Go, a numeric constant has no type, until its given one. One need to force typecast const to have it its type, like following

```go
const Big = 1 << 60
fmt.Println(int64(Big))
// => 1152921504606846976
```

{% hint style="info" %}
In Go, a numeric constant has no type, until its given one.
{% endhint %}


# Basic Types

Go does have a wide range of built-in types as well as allows the programmer to define custom types. We would discuss these later in depths. Here are some basic types that one should know before proceeding forward

```go
bool // holds boolean values
string // holds string values
int  int8  int16  int32  int64 // signed integer values
uint uint8 uint16 uint32 uint64 uintptr // unsigned integer values
byte // same as uint8
rune // alias for int32, represents a Unicode code point
float32 float64
complex64 complex128
```

Bit size of int, uint, uintptr depends on system architecture. On 32 bit system, they would be assumed to 32 bit wide, while on 64 bit system, they would be 64 bit wide.

Usually using `int` should suffice unless we have specific reason to use signed, unsigned or other varying types of integers/floats.

## Type Conversions

Go allows type conversion from one type to another via `T(v)` where `T` is type to cast to `v` is value to be typecasted.

{% hint style="warning" %}
In Golang, var of one type can not be assigned value of other type unless converted
{% endhint %}

```go
var age int = 23
var agef float64 = float64(age)
var ageu uint = uint(agef)
```


# Branching: If/Else

Go provides conditionals/branching via If/Else and Switch statements. These works mostly as they are intended to work, or one have seen them working in other programming languages. Here is very basic If statement in Go

```go
package main
import "fmt"
func main() {
    if 10%2 == 0 {
      fmt.Println("10 is even")
    }
}
// 10 is even
```

In Go, if statement returns true, block assigned to it will be evaluated, otherwise not. A `If` statement can be combined with `else` to give an option when statement evaluates to false. Lets change our example we used before

```go
package main
import "fmt"
func main() {
    var value = 9
    if value%2 == 0 {
      fmt.Printf("%d is even", value)
    } else {
      fmt.Printf("%d is odd", value)
    }
}
// 9 is odd
```

Simple, right. If/else can have multiple if else combined together making it more realistic to real world problems, like following

```go
package main
import "fmt"
func main() {
    var bmi = 9
    if value%2 == 0 {
      fmt.Printf("%d is even", value)
    } else {
      fmt.Printf("%d is odd", value)
    }
}
```

Here is BMI categories as available on [wikipedia](https://en.wikipedia.org/wiki/Body_mass_index). Lets create a simple Go program that would tell one, which category does one falls into

| Category                              | From | To   |
| ------------------------------------- | ---- | ---- |
| Very severely underweight             |      | 15   |
| Severely underweight                  | 15   | 16   |
| Underweight                           | 16   | 18.5 |
| Normal (healthy weight)               | 18.5 | 25   |
| Overweight                            | 25   | 30   |
| Obese Class I (Moderately obese)      | 30   | 35   |
| Obese Class II (Severely obese)       | 35   | 40   |
| Obese Class III (Very severely obese) | 40   |      |

```go
package main
import "fmt"
func main() {
    var bmi = 19.0
    if bmi <= 15.0 {
      fmt.Printf("Very severely underweight")
    } else if bmi > 15.0 && bmi <= 16.0 {
      fmt.Println("Severely underweight")
    } else if bmi > 16.0 && bmi <= 18.5 {
      fmt.Println("Underweight")
    } else if bmi > 18.5 && bmi <= 25.0 {
      fmt.Println("Normal (healthy weight)")
    } else if bmi > 25.0 && bmi <= 30.0 {
      fmt.Println("Obese Class I (Moderately obese)")
    } else if bmi > 30.0 && bmi <= 35.0 {
      fmt.Println("Obese Class II (Severely obese)")
    } else {
      fmt.Println("Obese Class III (Very Severely obese)")
    }
}
// Normal (healthy weight)
```

Change bmi value and see what would be program output

### If with short statement

In Go, If statement allows a short statement just before the condition; seperated by `;` and it would executed before conditional statement. For illustration consider following example

```go
package main
import "fmt"
func main() {
    if value := 7; value%2 == 0 {
      fmt.Printf("%d is even", value)
    } else {
      fmt.Printf("%d is odd", value)
    }
}
// 7 is odd
```


# Branching: Switch

Like any other programming language out there, `switch` is a shorter and more concise way to `if/else` . In Go `switch` runs the first case that matches the conditional expression.&#x20;

Go only runs first case that matches the conditional expression and unlike other language `break` is not required, it is implicitely provided by Go.

In Go, cases need not be constants, it could be any value or conditional statement to be evaluated. Here is first glance at simplest `switch` statement

```go
package main
import (
	"fmt"
	"runtime"
)
func main() {
	fmt.Print("Go runs on ")
	os := runtime.GOOS
	switch os {
	case "darwin":
		fmt.Println("OS X.")
	case "linux":
		fmt.Println("Linux.")
	default:
		fmt.Printf("%s.\n", os)
	}
}
// Go runs on Linux
```

{% hint style="info" %}
Notice, that it has automatically ejected once case matched to 'linux'
{% endhint %}

#### Switch with shorthand expression

In addition to this `switch` also allows short statement to be evaluated before the case. Above example can be redone like following (with short statement)

```go
package main
import (
	"fmt"
	"runtime"
)
func main() {
	fmt.Print("Go runs on ")
	switch os := runtime.GOOS; os {
	case "darwin":
		fmt.Println("OS X.")
	case "linux":
		fmt.Println("Linux.")
	default:
		fmt.Printf("%s.\n", os)
	}
}
// Go runs on Linux
```

#### Switch without condition

Go allows `switch` without condition and when there are no conditions, first case evaluating to true would be evaluated. For illustration consider following

```go
package main
import (
	"fmt"
)
func main() {
	switch {
	case true:
		fmt.Println("I am first statement")
	case true:
		fmt.Println("I am second statement")
	default:
		fmt.Println("You reached the bottom")
	}
}
// I am first statement
```

Seen that, though second case condition is also true, but Go has exited as soon as first condition evaluated to true

#### Switch allows multiple expressions

Go allows, multiple expression in case seperated by comma. The way it works is that whichever expression evaluates to true, following block will be executed. You can imagine a hidden or there in place of comma. Here is an illustration

```go
package main
import "fmt"
import "time"
func main() {
    switch time.Now().Weekday() {
    case time.Saturday, time.Sunday:
        fmt.Println("Yay! it's weekend")
    default:
        fmt.Println("it's still weekday, :(")
    }
}
```

In above code snippet, whenever `time.Now().Weekday()` evaluates to either `time.Saturday` or `time.Sunday` , first block will be executed else the default


# For loop

In Go, we have only one looping construct `for` But that powerful and more than enough than having multiple looping construct. Go's `for` can mimic many other looping construct, that we will see in a minute

In Go, a basic `for` loop construct looks like following

```go
for i:=1; i <= 10; i++{ 
  fmt.Println(i)
}
```

If you look at that example, it has three components

* init statement: where it assigns intial value, before looping starts
* Condition expression: condition to be evaluated before every iteration
* Post statement: statement to execute after every iteration

This is classical `for` loop construct that we have been using since we dived into programming. But in Go there is more to it, as mentioned earlier that this simple construct can take many forms. Take a look at following example

```go
i := 1
for {
  fmt.Println(i)
  i++
  if i == 10{
    break
  }
}
```

In illustration above, `for` loop does not have init, condition and post statement, as they are optional. Without them `for` loop will keep on going, so it becomes prorammer's prerogative to break out of loop. And that's exactly what `break` is doing in above illustration.

Go also allows programmer to use `for` loop without init and post statement as illustrated below

```go
i := 1
for i < 10 {
  fmt.Println(i)
  i++
}
```

following code snippet is also equal to what we have written above

```go
i := 1
for ; i < 10; {
  fmt.Println(i)
  i++
}
```


# Functions

Functions are fundamentals of Go. A function in Go can be declared with `func (v T) T{}` where v is value and T is type, while `func` is declaration. Function in Go require `return` explicitly, it will not automatically return last statement as value. Here is very basic function in Go

```go
func main(){
    fmt.Println("This is Awesome")
}
```

Yes, you see that right. We have been writing function since our first program. This is main function that always has to be part of `package main` and it is the entry point of program in Go

Though this function is very basic, it does not accept any parameter and not returning any value in this case. Lets write a trivial program that sums two integers

```go
package main
import "fmt"
func sum(a int, b int) int {
    return a + b
}
func main(){
    fmt.Print("Adding 1 and 2 equals: ")
    fmt.Println(sum(1, 2))
}
// Adding 1 and 2 equals: 3
```

The function `sum` takes two argument of type `int` and returns `int` . In Go, one can define multiple consecutive parameters of same type as once. For example, above example can be rewritten as

```go
package main
import "fmt"
func sum(a, b int) int {
    return a + b
}
func main(){
    fmt.Print("Adding 1 and 2 equals: ")
    fmt.Println(sum(1, 2))
}
// Adding 1 and 2 equals: 3
```

Here we can see that since a and b both are of same type and are consecutive parameters, we can define the type at once. Function in Go are called with there name followed by parameters in parenthesis. e.g `sum(1, 2)` &#x20;

#### Multiple return values

Function in Go can return, multiple return values of any types. For illustration look at the following example

```go
func AreaAndPerimeterSqr(a int) (int, int) {
    return a*a, 4*a
}
// Same can be called with
a, b := AreaAndPerimeterSqr(2)
```

This will automatically assign return values to a and b. There are sometimes where function returns multiple values but we only need one or two, but assigning those to variables and not using, will make Go complain about unused variable. To overcome this scenario  return value can be assigned to `_` . Hypothetically in example above, if we are not going to use area but only perimeter, then we can do something like this

```go
// To ignore value or related warnings for unused vars use _
_, b := AreaAndPerimeterSqr(2)
```

This would make Go not to complain unused variables.

### Variadic Function with Splat argument

Sometimes in some scenarios we need a function that would work with multiple number of arguments. In some programming languages this is achieved by method overloading, where you can have method with same name but varying signature. Go implements this in a simpler form called variadic function with splat argument

Do not get surprised but we are using a variadic function since our first program, `fmt.Println` . This function takes a varying number of argument of same type. for example below calls to `fmt.Println` are valid

```go
fmt.Println("Hello")
fmt.Println("Hello Go")
fmt.Println("Hello Go World")
```

Go allows programmer to write a variadic function with splat arguments. Let's re-write our `sum` function

```go
package main
import "fmt"
func sum(nums ...int) int {
    total := 0
    for _, num := range nums {
        total += num
    }
    return total
}
func main(){
    fmt.Println("1 + 2: ", sum(1, 2))
    fmt.Println("1 + 2 + 3: ", sum(1, 2, 3))
    fmt.Println("1 + 2 + 3 + 4: ", sum(1, 2, 3, 4))
    fmt.Println("1 + 2 + 3 + 4 + 5: ", sum(1, 2, 3, 4, 5))
    fmt.Println("1 + 2 + 3 + 4 + 5 + 6: ", sum(1, 2, 3, 4, 5, 6))
}

// 1 + 2:  3
// 1 + 2 + 3:  6
// 1 + 2 + 3 + 4:  10
// 1 + 2 + 3 + 4 + 5:  15
// 1 + 2 + 3 + 4 + 5 + 6:  21
```

You get the idea. Do not panic regarding `range` , we will soon be covering that


# Closures

> In [programming languages](https://en.wikipedia.org/wiki/Programming_language), a **closure**, also **lexical closure** or **function closure**, is a technique for implementing [lexically scoped](https://en.wikipedia.org/wiki/Lexically_scoped) [name binding](https://en.wikipedia.org/wiki/Name_binding) in a language with [first-class functions](https://en.wikipedia.org/wiki/First-class_function). [Operationally](https://en.wikipedia.org/wiki/Operational_semantics), a closure is a [record](https://en.wikipedia.org/wiki/Record_\(computer_science\)) storing a [function](https://en.wikipedia.org/wiki/Function_\(computer_science\)) together with an environment.
>
> Wikepedia.org

For a function to be clousers, at least; these following conditions should be met&#x20;

* Record storing function (retains copy of env/scope it is defined in)
* Can be passed around as a variable&#x20;
* Execution of clousers can be differed

Let see, if we can implement a clouser in Go. Dive in

```go
func Seq() func() int {
    i := 0
    return func() int {
        i += 1
        return i
    }
}
```

Let's look at the function, illustrated above; closely. we have defined a function `Seq()` that takes no argument and returns a value of type `func()` that in turn has a return value of type `int`&#x20;

Now lets see it in action

```go
mySeq := Seq()
mySeq()  // 1
mySeq()  // 2
mySeq()  // 3
mySeq = Seq()
mySeq()  // 1
```

Did you see that ?&#x20;

**Record Storing function**: So when we call `Seq()` for first time, it returns a function, with value of `i` encapsulated with it. So our variable `mySeq` holds a function and when we call it for first time, it increments the value of `i` to 1 and returns one, on subsequent call, it increments value of `i` on previously returned value, that prooves that it is keeping record of `i` .

**Can be passed around as a variable**: On our first call we assigned return value of function `Seq()` to local variable `mySeq` and it can be passed around freely, so it does satisfy our second condition

**Execution of clousers can be differed:** That also holds tru in this case, our variable holding function can be passed around; used with differ keyword and can also be passed to other context and executed later


# Recursion

A recursive function is a function that call itself unless it reaches matches a certain condition.&#x20;

{% hint style="warning" %}
A breakpoint for recursive function is necessary otherwise it could keep calling itself for indefinite times, growing heap and stack that could be detrimental to program's performance
{% endhint %}

We are going to implement a classic example to calculate factorial or given number using Go, with recursive methodology

```go
package main
import "fmt"
func factorial(n int) int {
    if n == 0 {
        return 1
    }
    return n * factorial(n-1)
}
func main() {
    fmt.Println(factorial(5))
}
// 120
```


# Array

In Go, array has to have its length declared at the time of declaration, limiting its users where length can not be determined. For example responses from third party api's etc. Array in Go can be declared with `[n]T` where n is length of array and T would be type of elements its going to hold.

Simplest array construct would look like this

```go
var array [3]int
fmt.Println("Empty Array: ", array)
// Empty Array: [0 0 0]
```

So we do see that we declared an integer array of size 3, since we did not specify elements, Go has initialized it with zeros of int, that are 0

Go allows one to assign values to an array by its index, for example to assign value 6 to array declared in previous example at index 2, one would write

```go
var array [3]int
array[2] = 6
fmt.Println("Array: ", array)
// Array: [0 0 6]
```

In Go, we can also initialize an array at the time of declaration with default values. See following example

```go
declared := [5]int{1, 2, 3, 4, 5}
```

In this, declared variable contains an array of lenth 5, holding values from one to five, in that order. Go also enables programmers to have two dimentional array, like following

```go
var vector [2][3]int
for i := 0; i < 2; i++ {
    for j := 0; j < 3; j++ {
        vector[i][j] = i + j
    }
}
```

In example illustrated above, vector variable hold array of lenth 2 that holds another array of lenth 3 holding integers.


# Slices

So to solve the problem we had at hand in previous chapter, Slices are Go's response to have array of dynamic length. But there is gotcha, one need to define length of slice at the time of declaration, but more data of same type could be appended to slices in future. For example

```go
slice := make([]string, 3)    // make is similar to new
fmt.Println("Empty:", slice)
```

So what we have done? We have defined a slice of type string having length 3. We can dynamically assign values to slices similar to array. In example above `make` is similar to new keyword. Like

```go
slice[0] = "apple",
slice[1] = "orange"
slice[2] = "banana"
```

To get the length of slices, we have similar `len` function as array

```go
len(slice) //=> 3
```

Go provides a special method called `append` for `slices`. this method actally creates a new slice with new lenght, assigning old and new element to it and returning a new slice. That returned slice should be saved in a variable to have access to it.

```go
slice := make([]string, 3)    // make is similar to new
fmt.Println("Empty:", slice)
slice[0] = "apple"
slice[1] = "orange"
slice[2] = "banana"
slice = append(slice, "peach")
slice = append(slice, "mango", "strawberry")
fmt.Println("Append:", slice)
```

Unlike Array, in Go slices has `copy` utility, that allows copying over slices. To copy our variable `slice` to `copied` variable, one can do like following

```go
copied := make([]string, len(slice))
copy(copied, slice)
```

In first line we make another slice of length of `slice` variable and then use `copy` function to copy over content of `slice` variable to `copied` variable

In addition to all those utility methods, Go provide a slice operator for slices, syntax for that looks like `[from:to]` where `from` is index number of slice to start from and go upto `to` index but excluding `to` . To illustrate, we would use our previous example

```go
sub = slice[2:5]
fmt.Println("sliced sub: ", sub)
// => sliced sub: [banana peach mango]
```

So, now its more clear. This has sliced from index 2 to 4 (excluding index 5). Similarly&#x20;

```go
// => This can be read as [0:5]
sub = slice[:5]
// => [apple orange banana peach]
```

Go also allows special syntaxfrom start index to length of slice

```go
// => This would copy over all elements fro index 4 to end
slice[4:]
// => [apple orange banana peach]
```


# Maps

Maps in Go are similar construct to `hash` or `dict` in other languages. You can assume it as a dictionary type where we can have a non integer index and corresponding values, kind of similar to JSON. A simplest example of map would be&#x20;

```go
myMap := map[string]int{"one": 1, "two": 2}
```

Simple syntax to declare map would be `make[kT]vT` , where kT is type of key and vT is type of value. In above illustration, we are declaring a map and assigning it some values. Maps can be access similar to arrays but we need to use key as an index. For example&#x20;

```go
myMap["one"]
//=> 1
```

To declare an empty map we could use something like this and then assign values at later stage.

```go
emptyMap := make(map[string]int)
// then assign values later
emptyMap["one"] = 1
emptyMap["two"] = 2
fmt.Println(len(emptyMap))
// =>  2
```

Did you notice one thing, like I did? We did not specify length of map at any stage, right? Because map in go defines the length internally and when we assign/append or delete values it keeps on defining new map with predicted length and release previous objects to be garbage collected

To delete a key from map, Go provides `delete` method. Syntax for delete is `delete(mapVar, key)` , where mapVar is variable that holds map and key is the key to be deleted. In our `myMap` example&#x20;

```go
delete(myMap, "one")
fmt.Println(myMap)
// map[two:2]
```

In Go, when querying a key returns two values, first one is value being hold against key, while second value is boolean, if that key existed or not, in first place. For illustration, consider following example

```go
myMap := map[string]int{"one": 1, "two": 2}
_, exist := myMap["three"]
fmt.Println(exist)
//=> false
```

It returned false, because there was no key `three` , Go does return zeros for type assigned for keys that does not exist


# Range

In Go, `range` is an iterator and can iterate over wide range of iteratable data types, including arrays, slices and maps. When iterated, range produces two variable for every iteration, first is index and second is value (in case of maps, first would be the key)

{% hint style="info" %}
In case of `maps` first variable produced would be the key and other one would be value assigned to that key
{% endhint %}

Simplest construct for `range` in Go would look like

```go
numbers := []int{1,2,3,4,5,6,7,8,9}
sum := 0
for i, number := range numbers {
    fmt.Printf("%d has %d", i, number)
    fmt.Println("\n")
    sum += number
}
fmt.Println("sum: ", sum)
```

Here `range` when iterating over variable `numbers` would assign index to i and value to number. One can ignore the index when not being used by assigning it to `_` . Just like we have seen in maps

Similarly `range` can be used to iterate over a slice and maps as well. Iterating over slice would be similar to arrays. Lets look at how it can iterate over maps

```go
myMap := map[string] string {"a": "apple", "b": "banana", "c": "cherry"}
for k, v := range myMap {
    fmt.Println(k, " has ", v)
}
// a  has  apple
// b  has  banana
// c  has  cherry
```

Go, in range allows us to skip first variable index or key by assigning it to `_` Like following

```go
myMap := map[string] string {"a": "apple", "b": "banana", "c": "cherry"}
for _, v := range myMap {
    fmt.Println(v)
}
// apple
// banana
// cherry
```

In Go, we can skip value altogether by not declaring variable for it. For illustration

```go
myMap := map[string] string {"a": "apple", "b": "banana", "c": "cherry"}
for k := range myMap {
    fmt.Println(k)
}
// a
// b
// c
```


# Pointers

Go includes pointers concept from C. But go limit these to enables programmers to pass by reference than by value. Go restrict on what can be done with pointers, like one can not manipulate pointers to point to some other address.\`

A basic pointer construct in Go looks like this

```go
package main
import "fmt"
func main() {
  i, j := 42, 2701
  // var p *int        // Holds pointer to int value
  p := &i              // Address of i
  fmt.Println(*p)      // read i through the pointer
  *p = 21              // set i through the pointer
  fmt.Println(i)       // see the new value of i

  p = &j               // point to j
  *p = *p / 37         // divide j through the pointer
  fmt.Println(j)       // see the new value of j
}
```

In illustration above, we can clearly infer that its mostly looks like how the construct is implemented in C, though with some restriction. To get the address of space (heap or stack) where the value hold by variable is stored, can be known by `&` operator.

While to get/set value stored at the address (considering the variable holds the address instead of value), one can use `*` operator. Confusing right? To simplify to get the address pointer for a variable use `&` operator, while when you have a pointer, then use `*` operator to manipulate the value at the address

* `p := &v` will return address of variable `v` and store it in var `p`&#x20;
* `*p = *p + 1` will manipulate v directly by reference, so prior statement will increment value of v by 1 (considering v is an int)

Since pointers can be confusing to many programmers out there, most specifically to programmers who have never written a piece of code in `C` So lets simplify this more.

We will define two methods, one will be getting a parameter by value and other one will be getting parameters by reference and they will try to change the value and then we will see, who has changed the value of actual variable that's been passed. For that lets define two function first

```go
func passByVal(val int){
 val += 1 // increment value by one 
}
func passByRef(val *int){
 *val += 1 // increment value by one at this address
}
```

So in example illustrated above, `passByVal` takes an int parameter and increase its value by one, similarly `passByRef` takes an int pointer parameter and increment value at that address by one. Now lets write a program to test hypothesis as explained above

```go
func main() {
    value = 1
    fmt.Println("Initial value:", value)
    passByVal(value)
    fmt.Println("Value after passByVal:", value)
    passByRef(&value)
    fmt.Println("Value after passByRef:", value)
}
// Initial value: 1
// Value after passByVal: 1
// Value after passByRef: 2
```

Did you see the output? When we passed value to `passByVal`, it assigned value of var `value` to local parameter `val` and then it has increased `val` by one, but this did not affect the original variable `value`. Why? because it has been passed by value and that duplicated/cloned it to some other variable holding some other space in heap, while the value of cloned variable did increment by one but not of the original parameter `value`&#x20;

In contrast to this, when we passed address of variable `value` instead of value itself to `passByRef` and passByRef changed value by manipulating value at pointer, it did change value of original parameter `value` . That's why we see value of variable `value` being increased by 1

{% hint style="info" %}
**Note:** The only caution to be taken is that to make sure that when a variable holds pointer to another variable, we manipulate it by referencing value at that pointer, instead of pointer itself
{% endhint %}


# Structs

{% hint style="warning" %}
This page is under active revision, content may be updated without notice
{% endhint %}

Go has a speciel type `struct` to define custome type with named fields. Struct act like collection of attributes/properties similar to classes in OOPs languages out there, but not exactly.

**Structs**

Struct can have named attributes of any type and methods can be defined to operate on that. Lets define a `Person` struct that will contain `first_name`, `last_name` and `age`

```go
type Person struct{
  first_name, last_name string
  age uint8
}
```

So that’s it, we just defined a person struct with some attributes. Let’s use it. There are many way to initialize an struct, here are some

```go
var p Person
```

Note when we initialize it without providing any value, go assign default value (zeros of type assigned) to each attributes, depending on there types, like `first_name`, `last_name` will be assigned a blank string "" and age will be assigned 0.

This can also be in initialized using `new` function that allocates memory and return pointer.

```go
p := new(Person)
```

But most used way is to initialize while passing values to it, here is how

```go
p := Person{first_name: "John", last_name: "Lego", age: 32}
//or we can leave off attribute names if we know order
p := Person{"John", "Lego", 32}
```

Attributes of a struct can be accessed by `.` operator. So to access `first_name` of `p` of type `Person` , one can use

```go
p.first_name // John
p.first_name = "Walker" // This would change first_name of object p
```

#### Struct with Pointers

Pointers with structs work in same way as they do generally in Go, but Go allows fields to be accessed without explicit de-referencing. For example

```go
package main
import "fmt"
type Person struct {
  Name string
  Age int
}
func main() {
  p := Person{"gopher", 2}
  pp := &p
  pp.Name = "Golang rocks"  // Same can be done via (*pp).Name
  (*pp).Name = "Golang rocks" // Similar to statement above
  fmt.Println(pp.Name)
  fmt.Println((*pp).Name)
}
```


# Methods

{% hint style="warning" %}
This page is under active revision, content may be updated without notice
{% endhint %}

In Go, Methods are similar to `func` except that they have a receiver to operate on. To get full\_name of a person we would love to define a method to `Person` struct like

```go
func(p Person) full_name() {
  fmt.Println(p.first_name, p.last_name)
}
p.full_name()
//=> "John Lego"
```

Well done Jack! But problem with this method is, it is printing `full_name` to standard output. But in real world we would need our `full_name` to return full name of a person. Here is how

```go
func(p Person) full_name() string {
  s := p.first_name + " " + p.last_name
  return s
}
fmt.Println(p.full_name())
//=> "John Lego"
```

Just FYI Jack, struct can also have embedded types, not just legacy types. Here is an example of struct `Employee`

```go
type Employee struct{
  Person
  employee_id string
}
```

Now to initilize it we need to follow same way, but first argument should be of type person, like

```go
e :=  Employee{Person{"Pankaj", "Bagwan", 26}, "emp101"}
fmt.Println(e.Person.full_name())
fmt.Println(e.full_name())
fmt.Println(e.employee_id)
```

Note that method defined on struct `Person` is alo available directly and indirectly to employee.


# Defer

In Go, a defer statement is similar to `final` or `ensure` in other programming language out there. It simply used for a cleanup for a function and most programming languages guarantee its execution at the end of function call or even when there are errors.

This can be used where we need to do some cleanup, like unsubscribe from a channel or close database connection etc.

Consider following simple example&#x20;

```go
package main
import "fmt"
func main() {
	defer fmt.Println("Go")
	fmt.Println("Hello")
}
// Hello
// Go
```

As we can deduce from example above `defer` gets called after the callee function is done returning. However, arguments for defer are evaluated at the time of declaration.

### Stacking Defer

Defer functions are stacked in a function stack, so in Go having multiple defer per function is allowed. Since `defer` are stacked so calls to it would behave like LIFO (last in- first out)

```go
package main
import "fmt"
func main() {
	for i := 0; i < 10; i++ {
		defer fmt.Println("Calling: ", i)
	}
	fmt.Println("Done")
}
// Done
// Calling:  9
// Calling:  8
// Calling:  7
// Calling:  6
// Calling:  5
// Calling:  4
// Calling:  3
// Calling:  2
// Calling:  1
// Calling:  0
```

So now it should be clear that out main function hash first stacked the defer calls to stack and made value of variable `i` available to defer. Once `main` has returned Go, started popping defer out of stack and executed them one by one


# Interfaces

{% hint style="warning" %}
This page is under active revision, content may be updated without notice
{% endhint %}

Golang implements interfaces as types and as collection of methods(specs for what should be considered of that type). Let’s first talk about collection of methods (specs that other types could implement)

```go
type Vehicle interface {
  Run() string
  Speed() int
  Stop() string
  Start() string
}
```

So what we did, is define a blueprint for Vehicle type, any type would be considered a vehicle that implements all methods listed in vehicle.

Let’s start defining some vehicles

```go
type Car struct { Odometer int }

func (c Car) Run() string{
  return "Running"  
}
func (c Car) Speed() int {
  return c.Odometer
}
func (c Car) Stop() string{
  return "Stopping"
}
func (c Car) Start() string{
  return "Starting"
}

type Truck struct { Odometer int }

func (t Truck) Run() string{
  return "Running"  
}
func (t Truck) Speed() int {
  return t.Odometer
}
func (t Truck) Stop() string{
  return "Stopping"
}
func (t Truck) Start() string{
  return "Starting"
}

type Bike struct { Odometer int }

func (b Bike) Run() string{
  return "Running"  
}
func (b Bike) Speed() int {
  return b.Odometer
}
func (b Bike) Stop() string{
  return "Stopping"
}
func (b Bike) Start() string{
  return "Starting"
}
```

Okay, so we defined three structs that implements out `Vehicle` interface. Now lets looks it in action

```go
func main(){
  vehicles := []Vehicle{ Car{ 100 }, Car{ 110 }, Bike{ 70 }, Truck{ 60 } }
  for _, vehicle := range vehicles {
    fmt.Println(vehicle.Start())
    fmt.Println(vehicle.Speed())
    fmt.Println(vehicle.Stop())
  }
}
// Starting
// 100
// Stopping
// Starting
// 110
// Stopping
// Starting
// 70
// Stopping
// Starting
// 60
// Stopping
```

SO here we creted a slice of type `Vehicle` and stuffed our structs implementing `Vehicle`, ieterating over them easily. If we assign type that does not implements, methods in `Vehicle` interface it can not be included in slice, let’s look at it

```go
type Jumbo struct {}

func main(){
  vehicles := []Vehicle{ Car{ 100 }, Car{ 110 }, Bike{ 70 }, Truck{ 60 }, Jumbo{} }
  for _, vehicle := range vehicles {
    fmt.Println(vehicle.Start())
    fmt.Println(vehicle.Speed())
    fmt.Println(vehicle.Stop())
  }
}
// cannot use Jumbo literal (type Jumbo) as type Vehicle in array element: 
// Jumbo does not implement Vehicle (missing Run method)
```

So this clearly not going to accept `Jumbo` in `Vehicle` slice as it does not implement `Vehicle`

Now we come to the next use of `interface`, that is type. In function’s argument signature can accept an interface type, meaning it could accept any type of value as those can be converted/casted to `interface`

```go
func PrintInterface( value interface{} ){
  fmt.Println(value)
}

func main(){
  PrintInterface( 80 )
  PrintInterface( "apple" )
  PrintInterface( 90.10 )
  PrintInterface( []string{"a", "b", "c", "d"} )
}
// 80
// apple
// 90.1
// [a b c d]
```


# Errors & Panic

In Go it is idiomatic to communicate errors explicitly, as separate return value. This contrasts with the exceptions used in languages like Java and Ruby. That meaning that Go leaves implementing error for programmer. Go implements error type and this would work similar to other primitive types.

In Go, programmer can create and error by calling `error.New` with a string passed to it as an error message. Consider the example bwlo

```go
func testError(a int) (int, error) {
  if a < 0 {
    return -1, errors.New("Negative number")
  }
  return a + 1, nil
}
```

`errors.New` constructs a basic error with a message, nil as second argument means no errors. Make a thumb rule to return error as last return value.&#x20;

{% hint style="warning" %}
**Note:** Some of you may have noticed weird return type compatibility in example above. But in Go, `nil` is considered of type error and hence they are compatible. Though it is still sounding weird to me :)
{% endhint %}

Go allows one to define custom error method, by implementing `Error()` method on any type. Consider the following example

```go
type MyError struct{
  stamp  time.Time
  msg    string
}
func (e *MyError) Error() string{
  return fmt.Sprintf("At %v - %s", e.stamp, e.msg)
}
func testError(a int) (int, error) {
  if a < 0 {
    return -1, &MyError{ time.Now(), "Cant process negative integers" }
  }
  return a + 1, nil
}
func main() {
  if _, err := testError(-1); err != nil {
    fmt.Println(err)
  }
}
```

In example as illustrated above, we have created a struct and defined a method `Error` on it

### Panic

Panic is a built-in function that stops the flow of control and begins *panicking*. When any function in Go calls pani&#x63;**,** execution of function stops immediately. Any deferred functions are executed normally, and then it returns to its caller.&#x20;

To the caller, then it behaves like a call to panic. The process keep continues up the stack until all functions in the current goroutine have returned, at which point the program crashes. One can imagine it like house of cards, where crashing one card in structure would almost crashes everything around. Or cascaded structure, where making one slip will crash up to the bottom of function call stack.

Panics can be initiated by invoking panic directly. They can also be caused by runtime errors, such as out-of-bounds array accesses. to call a panic in Go, simply call to`panic` will suffice. Consider following example

```go
panic()
```


# Goroutines

Go came to existance to solve problems being faced by today’s software, one of them is concurrency. Sol lets first understand what is concurrency?&#x20;

{% hint style="info" %}
In [computer science](https://en.wikipedia.org/wiki/Computer_science), **concurrency** is the ability of different parts or units of a program, algorithm, or problem to be executed out-of-order or in partial order, without affecting the final outcome. This allows for parallel execution of the concurrent units, which can significantly improve overall speed of the execution in multi-processor and multi-core systems. In more technical terms, concurrency refers to the decomposability property of a program, algorithm, or problem into order-independent or partially-ordered components or units.[\[1\]](https://en.wikipedia.org/wiki/Concurrency_\(computer_science\)#cite_note-1)
{% endhint %}

In simpler terms, Concurrency in computer programs is ability to execute pieces of program in parellel while providing control and communication among them. The execution of said pieces of programs can be in out of order or in partial order. To solve this Go has special construct called goroutines to execute pieces of programs in parallel.

Let see a how a goroutine can be defined in Go

```go
go someFunc(a, b, c)
```

In illustration above, while variables `a` , `b` and `c` happens in current goroutine but execution of `someFunc` happens in seperate goroutine. One can imagine goroutines as lightweight threads that are scheduled and controlled by Go. Goroutines runs in same shared address space so access to shared memory should be synchronised, go provides several primitives in `sync` package

By default, main function of package in go is run concurrently, implicitly. For expliit call we pass code block(that needs to be executed in routine) to `go`

```go
package main 

import "fmt"

func printer(a int){
  fmt.Println("a is: ", a)
}

func main(){
  fmt.Println("At the start")
  for i := 0; i < 10; i++ {
    fmt.Println("Sending to routine: ", i)
    go printer(i)
  }
  var get string
  fmt.Scanln(&get)
  fmt.Println("At the end!")
}

//At the start
//Sending to routine:  0
//Sending to routine:  1
//Sending to routine:  2
//Sending to routine:  3
//Sending to routine:  4
//Sending to routine:  5
//Sending to routine:  6
//Sending to routine:  7
//Sending to routine:  8
//Sending to routine:  9
//a is:  0
//a is:  1
//a is:  2
//a is:  3
//a is:  4
//a is:  5
//a is:  6
//a is:  7
//a is:  8
//a is:  9
//
//At the end!
```

Notice `fmt.Scanln(&get)`; this actually makes our main program to wait for inputs, otherwise it will exit before go routine actualy can print. A problem with this code is that, it looks synchronous, in order. To actually see that if goroutine are asynchronous, we need to make goroutine sleep for random time. Lets rewrite above illustration as:

```go
package main 

import(
  "fmt"
  "time"
  "math/rand"
)

func printer(a int){
  time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
  fmt.Println("a is: ", a)
}

func main(){
  fmt.Println("At the start")
  for i := 0; i < 10; i++ {
    fmt.Println("Sending to routine: ", i)
    go printer(i)
  }
  var get string
  fmt.Scanln(&get)
  fmt.Println("At the end!")
}

// time.Duration(rand.Intn(100)) will make goroutine sleep for varying time
//At the start
//Sending to routine:  0
//Sending to routine:  1
//Sending to routine:  2
//Sending to routine:  3
//Sending to routine:  4
//Sending to routine:  5
//Sending to routine:  6
//Sending to routine:  7
//Sending to routine:  8
//Sending to routine:  9
//a is:  9
//a is:  5
//a is:  6
//a is:  7
//a is:  2
//a is:  8
//a is:  3
//a is:  0
//a is:  4
//a is:  1
//
//At the end!
```

Look at this, now it is random. This illustrates that go routine are independent to each other and runs separately.

Now what we showcased so far is called parallelism, we still need to make them communicate to each other and `channels` comes to our rescue. Channels provide a mechanism of communication and synchronisation among goroutines. Lets look at example.

```go
package main

import (
  "fmt"
  "time"
)

func sender(ch chan int) {
  for i := 0; ; i++ {
    ch <- i
  }
}
func receiver(ch chan int) {
  for i:= 0; i < 10; i++ {
    message := <- ch
    fmt.Println("received: ", message)
    time.Sleep(time.Millisecond * 100)
  }
}
func main() {
    var ch chan int = make(chan int)
    
    go sender(ch)
    receiver(ch)
    
    var input string
    fmt.Scanln(&input)
}
```

That’s interesting. This is just a simple example of `channels` capabilities, there is much more that we have for channels in out next chapter.


# Buffered Channels

As hinted in previous Chapter, by default channels are not buffered (i.e does not hold value), meaning that connection has to be active with both ends (sending, recieving) being present. Buffered channel allows sent values to buffered (upto its capacity) until reciever recieves it.

This way sender can still enqueue messages in channel, without bothering about reciever being stuck or not attached. Lets look at example with buffer size two

```go
func main() {
    msg := make(chan string, 2)
    msg <- "Hello World"
    msg <- "Hola"
    fmt.Println(<-msg)
    fmt.Println(<-msg)
}
```

In above illustration, channel received first message `"Hello World"` and then while the message was still in the queue, it recieved another message `"Hola"` and recievers were not even defined by then. Buffered channel  can overflow in case buffer is full and we try to assign another value to it, ant throw panic

```go
    msg <- "Hello World"
    msg <- "Hola"
    msg <- "Holaa"            // will panic
    fmt.Println(<-msg)
    fmt.Println(<-msg)
    
    // fatal error: all goroutines are asleep - deadlock!
```

Buffer capacity of a channel can be known by using utility method, provided by Go `cap`&#x20;

```go
cap(msg)
// => 2
```


# Channels

In last [part](/advanced-go/goroutines), we talked about `goroutines` and channels. As discussed there is much more to channels, like channel direction, by default a channel is bi-directional, but it can be restricted to sending or receiving.

Lets first understand channels, channels in Go can be seen as pipe, that when data is put in at one end can be recieved at another end, where the both the ends are goroutine. In Go, channel can be defined as

```go
ch := make(chan int)
```

Above code defines a channel that can pass through an integer. By default channels are blocked until the reciever picks up the item supplied to it, then only sender can send next item.&#x20;

In sender, receiver example from previous [chapter](/advanced-go/goroutines), sender can only be restricted to sending, by redifining it like

```go
func sender(ch chan <- int) {
  for i := 0; i < 10 ; i++ {
    ch <- i
  }
}
```

So in above illustration `chan` followed by either `->` `<-` makes channel unidirection, in direction of arrow. So now channel `ch` in sender function can only recieve a value of type int.

Now sender can only send signal to channel `ch`. Similarly receiver can be restricted just to receive, by redifining it like

```go
func receiver(ch <- chan int) {
  for i := 0; i < 10 ; i++ {
    message := <- ch
    fmt.Println("received: ", message)
    time.Sleep(time.Millisecond * 100)
  }
}
```

Channel can be closed with utility finction `close`&#x20;

```go
close(ch)
```

That way we have restricted channel to only recieve a value of type int. By default channel are synchronous and blocking in nature. What do we mean by synchronous and blocking is that at any given time channel (as defined above) can hold only one value at a time, unless it is recieved by reciever. Once reciever has recieved previous value channel can hold another, otherwise it can in some scenarios result in **deadlock**.

To overcome this Go has provided buffered channel. We will talk about channel buffering in next Chapter


# Channel Synchronization

Channel can be used to synchronisze execution among goroutine, keep in mind that out main function is also run in goroutine. We have already seen that once goroutine is spawned from another goroutine, it runs seperately and the parent goroutine will exit once it is done running itself and will not wait for goroutine that it has created in process.&#x20;

Do you remember we used  `fmt.Scanln` that's because we wanted our main program to wait for unless user presses any key, actually we wanted to showcase console prints from goroutine and `fmt.Scanln` is a hack for that

But go does provide way to communicate between goroutines and by now we know that reciever is blocked until channel receives a message from sender. We can create a goroutine from our main goroutine with a channel that recieves a message of some kind from child goroutine and make our main program reciever for that message, done. Let's see that in action&#x20;

```go
func Blocker(finish chan bool) {
    fmt.Println("Started Working")
    time.Sleep(time.Second)
    fmt.Println("Done Working")
    finish <- true // Once blocker is done doing thing it notifies the channel
}
func main() {
    finish := make(chan bool)
    go Blocker(finish) // spawn blocker 
    <- finish          // wait for blocker to finish
}
// Started Working
// Done Working
// Program exited.
```

See, how simply we achieved with channels what we were trying to achieve with `Scanln` hack. But do notice

```go
<- finish
```

here since there is no reciever mentioned explicitly, current context itself is a reciever. There are several other way to wait for goroutines.


# Channel Direction (uni/bi)

{% hint style="warning" %}
This page is under active revision, content may be updated without notice
{% endhint %}

By default channels can receive and send, but channels direction can be controlled by restricting them to either send or receive (applicable only for method/func signature). This ensures safety where required. For example

```go
func Ping( c chan<- string, msg string){
  c <- msg
}
func Pong( c <-chan string, cc chan<- string ){
  msg := <-c
  cc <- msg
}
func main(){
  pic := make(chan string, 1)
  poc := make(chan string, 1)
  Ping(pic, "Pass the message")
  Pong(pic, poc)
  fmt.Println(<-poc)
}
```

#### Channels with Range and Close

Channel can be iterated over using range and can be closed. Channel, closed once will allow no more values to passed across.

```go
func fib(num int, c chan int) {
  x, y := 0, 1
  for i := 0; i < num; i++ {
    c <- x
    x, y = y, x+y
  }
  close(c)
}
func main() {
  c := make(chan int, 10)
  go fib(cap(c), c)
  for i := range c {
    fmt.Println(i)
  }
}
```


# Select

{% hint style="warning" %}
This page is under active revision, content may be updated without notice
{% endhint %}

In Go,  `select` statement lets a goroutine wait on multiple communication operations. A `select` blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready. Combining goroutines and channels with select is a powerful feature of Go.

```go
c1 := make(chan string)
c2 := make(chan string)
go func() {
    time.Sleep(time.Second * 1)
    c1 <- "Hello"
}()
go func() {
    time.Sleep(time.Second * 2)
    c2 <- "World"
}()
for {
    select {
        case msg1 := <-c1:
            fmt.Println("Received first message: ", msg1)
        case msg2 := <-c2:
            fmt.Println("Received second message: ", msg2)
            return
    }
}
```

Here we have put `select` statement within indefinite `for` loop. So It will keep on listening to channels unless it returns by calling `return` in one of them. In illustration above, when first anonymous goroutine function is called, it returns "Hello" to channel that in turn printed on I/O module (in our case cli), but select it does not finish, its ready to listens to another round of call and then second anonymous function is called and that does return, returning from select. And hence program exits

Golang's select lets you wait on multiple channel operations. Combining goroutines and channels with select is a powerful feature of Go.&#x20;

Go, also provides `default` case when no other cases match, default will run. In simplest form it would look like following

```go
select {
case i := <-c:
    // use i
default:
    // receiving from c would block
}
```


# Non-Blocking Channels

{% hint style="warning" %}
This page is under active revision, content may be updated without notice
{% endhint %}


# Waitgroups

{% hint style="warning" %}
This page is under active revision, content may be updated without notice
{% endhint %}

In previous chapters, we talked about how goroutines in Go language works. We have also seen several hacks to make our `main` program wait for goroutines. We have seen another strategy to make our `main` program wait in [Channel Synchronization](/advanced-go/channel-synchronization) chapter. we have gone through [Select](/advanced-go/channel-select) chapter. Today we will focus on providing robustness to our previous chapters by using semaphores from [sync](http://golang.org/pkg/sync/#WaitGroup) package, specially `sync.WaitGroup`

In Go, [sync.WaitGroup](https://golang.org/pkg/sync/#WaitGroup) implements three methods, `Add`, `Done` and `Wait` . We will discuss them at length. But before we jump for an example, in brief, goroutine with wait will wait for other goroutines (number of which are incremented by Add) to finish and call Done on WaitGroup before exiting.

Here is redone example from our previous chapter

```go
package main 

import(
  "fmt"
  "time"
  "math/rand"
  "sync"
)

var wait sync.WaitGroup // This creates a WaitGroup, to be used later

func Printer(a int){
  defer wait.Done() // Done signals that this gorutine is done doing work, decrementing semaphore counter
  time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
  fmt.Println("a is: ", a)
}

func main(){
  max_routine := 10
  wait.Add(max_routine) // This adds maximum counter to waithgroup should wait before terminating main program
  fmt.Println("At start")
  for i := 0; i < max_routine; i++ {
    fmt.Println("Sending to routine: ", i)
    go Printer(i)
  }
  wait.Wait() // This waits for semaphore counter to be 0 and then terminates current program
  fmt.Println("At end!")
}

// time.Duration(rand.Intn(100)) will make goroutine sleep for varying time
//At the start
//Sending to routine:  0
//Sending to routine:  1
//Sending to routine:  2
//Sending to routine:  3
//Sending to routine:  4
//Sending to routine:  5
//Sending to routine:  6
//Sending to routine:  7
//Sending to routine:  8
//Sending to routine:  9
//a is:  9
//a is:  5
//a is:  6
//a is:  7
//a is:  2
//a is:  8
//a is:  3
//a is:  0
//a is:  4
//a is:  1
//
//At the end!
```

Results may vary from machines to machines and specific to implementation. The message is that how one can leverage `sync.WaitGroup` api to synchronize goroutines. Believe me, illustration above is very basic example of what can be achieved with WaithGroup. But in essence what we did is, we imported `sync` package. `sync` package contains `WaitGroup` type, we declared variable `wait` to be of WaitGroup type. `Waitgroup` provides three methods namely `Add`, `Done` and `Wait`.

1.) `Add` method takes integer as a parameter delta to the counter, and once counter becomes zero, all blocking goroutines, waiting onto counter would be released. We provided no of goroutines we are going to wait upon

{% hint style="warning" %}
Note, that in illustration above, we provided our goroutine count at once to be 10. But in practical scenario, calling `wait.Add(1)` will increment counter by one.&#x20;
{% endhint %}

2.) `Wait` methods waits for semaphore counter to become zero, before releasing goroutines, waiting onto other goroutines to terminate/finish. In illustration above, we are making our main program to wait for other goroutines to finish.

3.) `Done` method basically indicates that current goroutine, in which this is being called is done/finished, while decrementing semaphore counter. Our goroutines calls to `Done` method indicating that goroutine is done executing its task.


