Getting started with Golang: a tutorial for beginners
Tags: go, codenewbie, google
Published: 2020-04-29 23:03:24

**Golang**, also known as Go, is an open-source programming language created by Google developers Robert Griesemer, Ken Thompson, and Rob Pike in 2007. It was created for ease, and many developers praise it for building simple, reliable programs.

Since its release, Golang has gained increasing popularity. In 2009 and 2016, it was pronounced [the language of the year](https://www.tiobe.com/tiobe-index/). It was given the 10th place ranking in 2018, and it continues to move its way into [major organizations](https://hub.packtpub.com/why-golan-is-the-fastest-growing-language-on-github/). 

This language has a lot to offer. Anyone wanting to work at Google should know this language. That’s why today, I want to walk you through a deep-dive tutorial to the Go programming language. 

Today we will discuss: 
* Overview of Golang features 
* Basic terms and concepts of Go
* Intermediate concepts of Go
* Advanced concepts of Go
* Resources 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4uior22ciwwkotiwzheb.png)

## Overview of Golang features 

This general-purpose programming language includes [many great features](https://www.freecodecamp.org/news/here-are-some-amazing-advantages-of-go-that-you-dont-hear-much-about-1af99de3b23a/) from other programming languages. It is compiled, simple, concurrent, statically-typed, and efficient. Go improves upon these aspects of programming languages and simplifies the working environment for developers. 

Go is essentially an imperative language that accommodates concurrency concepts. It brings some of the great features of object-oriented programming, like interfaces, but does not include some of the pitfalls. Go was intentionally designed to exclude the more “heavy-weight” features of OOP. 

In that respect, Go is **hybrid**, utilizing the best features of many languages with a clear, expressive type system while remaining lightweight and easy to learn. 

Go can be used for all kinds of software development solutions such as a system programming language, a general programming language, or general support. It can handle heavy server-centric web services, text-processing problem, and heavy-duty distributed applications.  

<br>

### Why learn Golang?
 
**Familiar and easy to learn.** Go belongs to the C-family, so it shares many beloved syntactic similarities to languages like Java and C++, but Go offers a more concise syntax, so it’s easier to learn and read. Similar to Python and Ruby, it also integrates many features of dynamic programming. 

**Meets developer needs.** Go attempts to meet some common needs that developers face. It speeds up the software development process while not compromising on efficiency. Go aims to support the developing market with network communication, memory management, and speed. 

**Simplicity of server-side.** Go makes it easy to work with the server-side of your code. The standard Go library provides the standard HTTP protocol. 

Now that we have a sense of what Go is and what it brings to the table, let’s jump into the basics. Today, we will be introducing the major concepts and core constructs of the Go programming language to get you started. As always, a more robust course is needed to teach you all the ins-and-outs.

*Let’s jump in.*

<br>

___

## Basics terms and concepts of Go

### Filenames, keywords, identifiers 

The **Go source code** is stored in `.go` files. All filenames are lowercase, and you can use `_` to separate multiple words. As with most filenames, you cannot use spaces or special characters.

**Keywords** in Go function similarly to most programming languages. These are reserved words that carry special meaning to use in your code. Unlike Java or C++, Go has far fewer keywords, making it easier to use and learn. These keywords are:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7101azpjopsys6h6nckn.png)

**Identifiers** are similar to keywords, but you make these as the programmer. You can assign a name to elements like variables, templates, etc. And like most programming languages, identifiers are case sensitive. They must begin with a letter or an underscore and are followed by digits. The blank identifier `_` can be used in declarations or variable assignments. There are also 36 predeclared identifiers, which are:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nbli5qgqd28q0axvrgdc.png)

<br>

### Basic structure

Programs in Go are built up of keywords, operators, types, functions, and constants. Code is structured in statements, but it does not need to end with a `;` like many other C-family languages. If multiple statements are written on one line, you must separate them with `;`.

Go uses similar punctuation characters to other languages, including `.` `,`  `;` `:` and  `...`.

Go uses three delimiters in its code: `( )`  `[ ]` and `{ }`.

<br>

### Data types and variables

Like many programming languages, **variables** contain different types of data that define the set of values or operations that can act upon those values. In Go, there are four main data types you can work with:

* Elementary (aka. primitive): `int`, `float`, `bool`, `string`
* Structures (aka. composite): `struct`, `slice`, `map`, `array`, `channel`
* Interfaces: describe the behavior of a type

In Go, a structured type has no inherent value but rather the default value `nil`.

A **variable** is a value that can be changed during execution. To declare a variable, we use the `var` keyword. 

```go
var identifier type = value
```

In this example, `identifier` is the name of the variable, and `type` is the type. Unlike other C-family languages, we write `type` after the variable `identifier`. When we declare a variable in Go, memory is initialized. We must also give a value to our variables using the `=` operator. This process is called assigning a variable. 

There is also a shorthand for declaring variables.

```go
   f := "fruit"
    fmt.Println(f)
}
```

<br>

### Operators 

Like in many programming languages, **operators** are built-in symbols that perform logical or mathematical operations. There are three types of operators in Golang, arithmetic, logical, and bitwise. 

**Logical operators** are similar to other programming languages. Go, however, is very strict about the values that can be compared. These operators include:
* Equality operator` ==`
* Not-Equal operator` !=`
* Less-than operator `<`
* Greater-than operator `>`
* Less-than equal-to operator `<=`
* Greater-than equal-to operator `>=`


**Bitwise operators** work on integer variables that have bit-patterns of equal length. Some of the bitwise operators are:
* Bitwise AND operator `&`
* Bitwise OR operator `|`
* Bitwise XOR operator `^`
* Bit CLEAR operator `&^`
* Bitwise COMPLEMENT operator `^`

**Arithmetic operators** include `+` `/` `%` and `*`. 

These perform common arithmetic operations, and there are even some shortcuts. For example, 
```go
b = b + a
``` 
can be shortened as 

```
b += a
```

<br>

### Strings

**Strings** implement functions to manipulate UTF-8 encoded strings. They are `UTF-8` encoded by default, so they can contain characters from any language. These are defined between double quotes `“ “`, can include a sequence of variable-width characters, and are immutable. 

Go strings are generally better than strings in other languages because they use less memory, and you don’t need to decode them due to the UTF-8 standard. 

There are two kinds of string literals in Golang, interpreted and raw. **Interpreted strings** are surrounded by  quotes, and **raw strings**  are surrounded by backticks. 

To declare a string, we use the `string` keyword. Look at the example below to see how it’s done. 

```go
package main
import "fmt"

func main() {
  var s string = "Hello, World"
  fmt.Printf(s)
}
```

*Output:* Hello, World

You can loop over characters in a string to access individual elements. We use the `for` loop, which we will discuss more later. 

```go
package main
import "fmt"

func main() {
  var s string = "Hello, World"
  
  for index, character := range(s){
    fmt.Printf("The character %c is in position %d \n", character, index)
  }
}
```

*Output:* 
The character H is in position 0 
The character e is in position 1 
The character l is in position 2 
The character l is in position 3 
The character o is in position 4 
The character , is in position 5 
The character   is in position 6 
The character W is in position 7 
The character o is in position 8

You can also use string to form a string from a slice of byte values. Look at the example to see how it’s done. 


```go
package main
import "fmt"

func main() {
  myslice := []byte{0x48, 0x65, 0x6C,  0x6C, 0x6f} 
  mystring := string(myslice) 

  fmt.Printf(mystring)
}
```

*Output:* Hello


<br>

### Times and dates
 
In Golang, the package `time` provides the ability to measure and display time. For example, we can use `time.Now( )` to display the current time, and `t.Day ( )` to obtain smaller parts. There are many useful features of Go’s `time` package, such as the function `Since(t Time)`, which returns the time elapsed since `t`. 
You can make your own time formats as well.

```go
t := time.Now()
fmt.Printf("%02d.%02d.%4d\n", t.Day(), t.Month(), t.Year()) // e.g.: 29.10.2019
```

For more on Go's `time` package, check out the [documentation](http://golang.org/pkg/time/).

<br>


> ## Keep the learning going. 
> Learn Golang without scrubbing through videos or documentation. > Educative's text-based courses are easy to skim and feature live coding environments - making learning quick and efficient. 
>
> [The Way to Go](https://www.educative.io/courses/the-way-to-go)


<br>

___

## Intermediate concepts of Go

### Control structures 

**Control structures** are similar to that of C, but they are generally more simplified and flexible. There are no `do` or `while` loop; instead, Go uses flexible `for` and `switch` loops. 

There are also new control structures, such as a type switch and `select`. We do not use parentheses, and the bodies are brace-delimited. Let’s take a deeper look at Go control structures. 

**`if-else`**: this construct tests for a conditional statement, either logical or boolean. If a statement is `true`, the body between the { } is executed. If it is `false`, the statements are ignored, and the statement after the `if` is executed.  Keep in mind that the braces are mandatory even if there is only one statement in the body. 

**`switch-case`:** this structure is used instead of long `if` statements that compare variables to values. This statement makes it easy to transfer-flow of execution in your code.  

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ndeeft3fwhiguld7uftz.png)

`switch` is generally more flexible than other languages. It takes this general form. 

```go
switch var1 {
case val1:
...
case val2:
...
default:
...
}
```

Like the `if` construct, a `switch` can also contain an initialization statement. 

```go
switch initialization; {
case val1:
...
case val2:
...
default:
...
}
```

**`select`:** this statement means we can wait on multiple channel operations, which we will discuss more later. 

**`for-range`:** in Go, this statement allows us to iterate over an expression that evaluates to an array, slice, map, string, or channel. The basic syntax is below.

```go
for index, value := range mydatastructure {
        fmt.Println(value)
    }
```

* `index`: the index of the value we want to access.
* `value`: the value on each iteration.
* `mydatastructure`: holds the data structure whose values we are accessing in the loop.

> Keep in mind that this example is a generalization. To learn more about case-by-case examples, take a look at the EdPresso shot on the `for-range` loop [here](https://www.educative.io/edpresso/what-is-the-for-range-loop-in-golang) 

<br>

### Functions 

**Functions** are the basic building blocks of Golang, as it shares many features of functional languages. As I mentioned before, functions are data since they have values and types. A Go program is built up of several functions. It is best to start with `main( )` function and write them in calling, or logical, order. 

Functions break down problems into smaller tasks and enable us to reuse code. There are three types of functions in Go. All of them end when they have executed their last statement before `}` or when it executes a return statement.
* Normal functions that use an identifier 
* Anonymous or lambda functions 
* Methods 

We write functions using this syntax, and we call them with this general format. 

```go
func g() { // VALID
 ...
}
```

and we call them with this general format. 

```go
pack1.Function(arg1,arg2,...,argn)
```

Here `function` is a function in `pack1`,  and `arg1`is the argument. When we invoke a function, it makes copies of the arguments, which are passed to the called function.

Let’s take a look at an example of a function to see Go in action. Here, we will dive into the `printf( )` function in Golang. The `print` function allows you to print formatted data. It takes a template string that contains the text we will format and some annotation verbs that tell the `fmt` functions how to format.

```go
fmt.printf("Sample template string %s",Object arg(s))
```

Conversion characters tell Golang how to format the data types. Some common specifiers are:
* v – formats the value in a default format
* d – formats decimal integers
* g – formats the floating-point numbers
* b – formats base 2 numbers 

Say we wanted to print a string. The `%s` conversation character can be used in the template string to print string values. Look at the code below.
There are many other cases where we can use the print function. To see more, take a look at the EdPresso shot on the [Golang print function](https://www.educative.io/edpresso/how-to-use-the-printf-function-in-golang). 



```go
package main
import "fmt"

func main() {
  var mystring = "Hello world"
  fmt.Printf("The string is %s", mystring)
}
```

*Output:* The string is Hello World


<br>

### Maps

**Maps**, also called hashes or dicts in other programming languages, are a built-in data type in Go. The name explains their purpose: a map *maps* keys to values. Think of a map as a way to store key-value pairs. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gbsqf0q9332ime0buey4.png)

You can use these for fast lookups, retrievals, or deletion of data based on keys. 
We declare a map using the following syntax

```go 
var m map[KeyType]ValueType
```

* `m` is the name of the map variable
* `KeyType` is the option data type of the keys in the map. This can also be declared at the time of initialization. 
* `ValueType` is the data type of the value in the key-value pairs.

The length of a map doesn’t need to be known at declaration, so it can grow dynamically. The value of an uninitialized map is `nil`. 
Let’s look at a specific example of a map in Golang to see how they are made:

```go
package main
import "fmt"

func main() {
  var mapLit map[string]int   // making map
  var mapAssigned map[string]int
  mapLit = map[string]int{"one": 1, "two": 2}   // adding key-value pair
  mapCreated := make(map[string]float32)        // making map with make()
  mapAssigned = mapLit
  mapCreated["key1"] = 4.5      // creating key-value pair for map
  mapCreated["key2"] = 3.14159
  mapAssigned["two"] = 3        // changing value of already existing key
  fmt.Printf("Map literal at \"one\" is: %d\n", mapLit["one"])
  fmt.Printf("Map created at \"key2\" is: %f\n", mapCreated["key2"])
  fmt.Printf("Map assigned at \"two\" is: %d\n", mapLit["two"])
  fmt.Printf("Map literal at \"ten\" is: %d\n", mapLit["ten"])
}
```

*Output:*
Map literal at "one" is: 1
Map created at "key2" is: 3.141590
Map assigned at "two" is: 3
Map literal at "ten" is: 0

<br>

### Arrays and slices

**Arrays** in Go are similar to Python, but they aren’t very common in Go code because they are inflexible and have a fixed size. Instead, **slices** are far more common and provide greater power. Slices in Go build off of arrays, since it is an abstraction of Go’s array type. 

To declare an array, we use the following syntax:

```go
var identifier [len]type
```

An array is fixed in size since its length is part of its type. For example `[5]int` represents an array of five integers. A slice allows us to overcome some of the challenges of arrays and work with sequences of typed data without using additional memory. 

A slice is a reference to a continuous section of an array, called the underlying array. A slice is dynamically sized and flexible. A slice is formed when we specify two indices, separated by a colon. We use the type specification `[ ]T`. T is the type of elements in the slice. We declare a slice using the following syntax: 

```go
letters := []string{"a", "b", "c", "d"}
```

To declare the type for a variable with a slice, we use `[ ]` with the type of elements for the slice.

```go
package main

import (
	"fmt"
	"reflect"
)

func main() {
	var intSlice []int
	var strSlice []string

	fmt.Println(reflect.ValueOf(intSlice).Kind())
	fmt.Println(reflect.ValueOf(strSlice).Kind())
}
```

A slice, unlike an array, can change during execution. Additionally, slices come with the built-in `append`, which can return a slice that contains one or more new values. The syntax of the `append` method is:

```go
slice = append(slice, elem1, elem2, ...)
```

Take a look at how it's done. 

```go
package main
import "fmt"

// Helper function to. print slices
func printSlice(s []int) {
	fmt.Printf("length=%d capacity=%d %v\n", len(s), cap(s), s)
}

func main() {
	var slice []int // Create an empty slice of type int.
	printSlice(slice)

	// Append works on nil slices.
	slice = append(slice, 0)
	printSlice(slice)

	// Slices can be appended to as many times.
	slice = append(slice, 1)
	printSlice(slice)

	// We can add more than one element at a time.
	slice = append(slice, 2, 3, 4)
	printSlice(slice)
}
```

*Output:* 
length=0 capacity=0 []
length=1 capacity=1 [0]
length=2 capacity=2 [0 1]
length=5 capacity=6 [0 1 2 3 4]

Now that we have a sense of some of the intermediate Go concepts, let’s move onto some of the important advanced things that Golang brings to the table. Keep in mind that there is a lot more to learn. Some other intermediate concepts include: 
* Recursive functions 
* Higher order functions
* Structs and methods
* Interfaces and reflection 
* and more

<br>

___


## Advanced concepts of Go 

### Error handling 

Go does not have an exception-handling mechanism. We use the built-in interface type `error`. It’s zero value is `nil`, so we know that there were no errors if it returns `nil`. The most common way to handle errors is to return the `error` type as the last return value of a function call to check for `nil`. Let’s take a look at some code to see how it’s done. 

```go
package main
import "fmt"
import "errors" // Import the errors package.

func divide(x int, y int) (int, error) {
	if y == 0 {
    return -1, errors.New("Cannot divide by 0!")
  }
  return x/y, nil
}

func main() {
  answer, err := divide(5,0)
  if err != nil {
    // Handle the error!
    fmt.Println(err)
  } else {
    // No errors!
    fmt.Println(answer)
  }
}
```

*Output:* Cannot divide by 0!



<br>

## Goroutine

Go comes with built-in support for concurrent applications. These are programs that execute different pieces of code simultaneously. The basic building blocks for structuring concurrent programs are **[goroutines](https://tour.golang.org/concurrency/1)** and **[channels](https://tour.golang.org/concurrency/2)**.

Unlike Java, concurrency support is baked into the language with specific types (chan), keywords (`go`, `select`) and constructs (goroutines). Go emphasizes concurrency rather than parallelism because Go programs may not be parallel by default. Only a single core or processor is used for a Go program, regardless of the goroutines running. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/l96umtn5x04jwj5q68f4.png)

So, what are goroutines? They are methods or functions that run alongside other methods or functions. These are determined by how we call them. Think of these like threads, but they are much easier and more lightweight. 

We use the keyword `go` to create a goroutine, so when we call a function or method with that prefix, a goroutine is executed.
 
If you want a more robust introduction to Goroutines, check out the article [Anatomy of goroutines in Go](https://medium.com/rungo/anatomy-of-goroutines-in-go-concurrency-in-go-a4cb9272ff88). 

You can use the variable `GOMAXPROCS` to tell the run-time how many goroutines can execute. `GOMAXPROCS` must be set to more than the default value 1, or else all goroutines will share the same thread. Let’s look at an example.


```go
package main
import (
"fmt"
"time"
)

func main() {
  fmt.Println("In main()")
  go longWait()
  go shortWait()
  fmt.Println("About to sleep in main()")
  time.Sleep(10 * 1e9) // sleep works with a Duration in nanoseconds (ns) !
  fmt.Println("At the end of main()")
}

func longWait() {
  fmt.Println("Beginning longWait()")
  time.Sleep(5 * 1e9) // sleep for 5 seconds
  fmt.Println("End of longWait()")
}

func shortWait() {
  fmt.Println("Beginning shortWait()")
  time.Sleep(2 * 1e9) // sleep for 2 seconds
  fmt.Println("End of shortWait()")
}
```

*Output:* 
In main()
About to sleep in main()
Beginning longWait()
Beginning shortWait()
End of shortWait()
End of longWait()
At the end of main()

Here, the program indicates the part of the execution phase that the program is in. The functions `main( )`, `shortWait( )`, and `longWait( )` start as independent processing units and then work concurrently.

Channels are used with goroutines to enable *communication* between them. These are typed message queues that transmit data. Think of it as a conduit that you can send typed values through. This way, we can avoid shared memory between goroutines. A channel can transmit one datatype, but we can make them for any type.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/p9zcsz7zhz5p6tx70d53.png)

To declare a channel, we use the following format

```go
var identifier chan datatype
```

A channel is also a reference type, so, to allocate memory, we use the `make( )` function. Below, see how to declare a channel of strings and its instantiation. 

```go
var ch1 chan string
ch1 = make(chan string)
```

<br>

### The Standard Library and Packages

The Go-distribution includes more than 250 built-in packages, and the API is the same for all systems. Each package introduced different functionalities to your Go code. See the documentation [here](https://golang.org/pkg/#stdlib). 

Let’s introduce some common packages to see what it has to offer. 
* `os/exec`: gives the possibility to run external OS commands and programs.
* `syscall`: this is the low-level, external package, which provides a primitive interface to the underlying OS’s calls.
* `archive/tar` and `/zip – compress`: contains functionality for (de)compressing files.
* `fmt`: contains functionality for formatted input-output.
* `io`: provides basic input-output functionality, mostly as a wrapper around os-functions.
* `bufio`: wraps around io to give buffered input-output functionality.
* `path/filepath`: contains routines for manipulating filename paths targeted at the OS used.
* `strconv`: converts strings to basic data types.
* `unicode`: special functions for Unicode characters.
* `regexp`: for string pattern-searching functionalities.

There are also external third-party Go packages that can be installed with the `go get` tool. You need to verify that the GOPATH variable is set, otherwise, it will be downloaded into the **$GOPATH/src**	 directory. Check that out [here](https://github.com/golang/go/wiki/Projects). 

There are more than 500 useful projects that you can introduce to your Go program. When introducing new functionality to an existing project, it’s good to incorporate a pre-existing Go library. This requires knowledge of the library’s API, which constraints the methods for calling the library. Once you know the API, call the library’s functions and get started. 

Let’s look at the complete code of importing an external library. 

```go
package main
import (
"fmt"
"time"
"github.com/inancgumus/myhttp"
)
 
func main() {
  mh := myhttp.New(time.Second)
  response, _ := mh.Get("https://jsonip.com/")
  fmt.Println("HTTP status code: ", response.StatusCode)
}
```

Now we have a sense of some of the advanced concepts in Go. There is a lot more to learn, including:
* Interfaces and Reflection 
* Error testing 
* Anonymous channel closure
* Networking, templating, and web-applications 
* Best practices and pitfalls
* and more

<br>


___

## Resources 

Golang is an exciting language that speeds up development and accommodates your real-world needs. Luckily, there are dozens of useful resources to learn, practice, and share Go with the world. Take a look below to get started. 

<br>

### Courses
* [**The Way to Go:**](https://www.educative.io/courses/the-way-to-go) the definitive place to learn the core constructs and techniques of Go with hands-on practice
* [**Introduction to Programming in Go:**](https://www.educative.io/courses/introduction-to-programming-in-go) detailed instruction for beginners 
* [**Mastering Concurrency in Go:**](https://www.educative.io/courses/mastering-concurrency-in-go) for intermediate Go learners looking to upskill 

<br>

### Documentation and Guides 
* [**Tour of Go:**](https://tour.golang.org/welcome/1) official Go tutorial
* [**Official Golang Documentation:**](https://golang.org/doc/) dive deeply into the code
* [**GitHub Go Bootcamp:**](https://github.com/GoBootcamp/clirescue) learn by practicing, for beginners

<br>

### Learn from other developers
* [**Why you should learn Go in 2020**](https://medium.com/@meeusdylan/why-you-should-learn-go-in-2020-6ce975b66d47)
* [**Advantages of Using Go from FreeCodeChamp**](https://www.freecodecamp.org/news/here-are-some-amazing-advantages-of-go-that-you-dont-hear-much-about-1af99de3b23a/) 
* [**Pros and Cons of Using Go**](https://hackernoon.com/should-i-go-the-pros-and-cons-of-using-go-programming-language-8c1daf711e46)