Introduction to the Go programming language and why you should learn it

Since its first release in 2009, Go (also known as Golang) has continuously increased in popularity and has been adopted by big and small companies alike mostly in place of dynamic environments such as Python, Ruby, and Node.js. The language has a lot to offer and is well worth learning in 2020 and beyond.

Go is an imperative, statically typed, compiled programming language first developed at Google by Rob Pike, Robert Griesemer, and Ken Thompson in 2007 and open sourced in 2009. It was developed as a reaction to the perceived shortcomings of existing languages and environments which made developing large software systems to be slow and clumsy.

At the time when Go was first designed, Java and C++ were the most commonly used languages for writing servers at Google and these languages had not evolved properly to take full advantage of modern hardware advancements.

Slow build times, uncontrolled dependencies, poor documentation, and an inability to effectively use hardware resources were some of the other problems that were associated with those languages at the time. Another major concern was the growing complexity that made the maintenance of systems developed in those languages to be tedious and inefficient.

Due to these issues, some people were beginning to adopt dynamic languages like Ruby and Python for their server side projects. These languages required no compilation time which was a boon for productivity, but they lacked the performance characteristics and type safety of statically typed languages which often caused hard to track bugs.

Go was designed to provide the best of both worlds: a statically typed, fast to compile, and fast to execute language that remained easy to reason about even at the scale of a really large software project.

Uses of Go

The authors of Go originally envisaged it as alternative to the likes of C++, but that’s not really how it has been adopted over the years. Go is mostly used in places where companies would normally opt for Python, Node.js or Java. In particular, Go is great for:

  • Cloud and networking services
  • Web development
  • Command line tools
  • DevOps and automation tools

If your use case falls into one of the above categories, it’s likely that Go would be a great option for you to consider. To give you a sense of the how Go is being used in the real world, here’s a few examples:

  • Stream uses Go to power its real time chat and feeds infrastructure. They switched from Python and found that Go is typically 40 times faster for their use case.
  • Iron uses Go to build their background job processing system based on Docker. They switched from Ruby and reduced their number of servers from 30 to 2.
  • Twitch uses Go to power many of its busiest systems that serve live video and chat to millions of users.
  • Popular DevOps tools such as Docker and Kubernetes are written in Go.

Why you should learn Go

As mentioned earlier, Go provides many of the benefits of programming in a dynamic language without any of the downsides. It’s designed to be simple and easy to reason about, so it omits a lot of the crazy programming syntax and features that are present in other mainstream languages. This makes it relatively easy to learn and teach others.

It also features speedy compilation times and exceptional performance that blows past dynamic languages like Python or Ruby although it’s generally slower than C++ or Rust. But then again, Go was not designed to function as “low” as either language.

Go’s “batteries included” standard library is often lauded as one of its best features. It is extensive, cross platform, well documented and provides everything you need to build networking services or CLI tools without pulling in any third-party packages. Common use cases like string manipulation, file and network I/O, testing, templating, JSON and so much more are well catered for by the standard library.

The language is also really stable with a strict compatibility promise that guarantees that any Go 1.x program will run unchanged on later 1.x versions of the language. For instance, a program that runs under Go 1.13 should be compatible with Go 1.14, Go 1.15, and so on without modification.

Deploying Go programs is a piece of cake as you don’t need to install a runtime or go through any convoluted steps. The go build command will compile your program into a single binary that you can deploy to your desired platform. You can even build Go binaries that target operating systems and architectures other than your own by customising some environmental variables.

Demand for Go developers is also on the rise as more companies adopt the language for their cloud services and tooling. For example, Hired found Go to be the most in-demand language on their platform in 2019. Go developers also command a high salary, second only to Scala in the United States according to StackOverflow’s 2020 survey.

StackOverflow highest paying languages 2020

Concurrency is another strong point for Go. It provides lightweight but powerful concurrency features (goroutines and channels) that ensures your software will be able to effectively use the resources of the hardware it runs on. Go also has a garbage collector that is optimised for low latency so you don’t have to manage your own memory.

Install Go

If you just want to play around with Go without committing, you can use the Go playground to get a feel for its syntax, and to write simple programs. However, if you’re serious about learning Go, you need to install it on your computer first.

The Go team provides pre-built binaries for Window, macOS and Linux. The option to install from source is also available if you use a different operating system from the aforementioned trio.

Linux

You have a few options to install Go on a Linux machine. If you have Snaps installed on your computer already, you can get the latest version of Go by running the command below.

$ sudo snap install go --classic

Otherwise, you can check if your preferred distribution packages Go in its repositories. For example, Arch users can use the command below to install Go:

$ sudo pacman -S go

The main caveat with the above method is that you may not always get the latest version, especially if your distro does not follow a rolling release schedule.

The guaranteed way to get the latest version of Go is to download the Go distribution archive for Linux and extract it to the /usr/local/ directory:

$ sudo tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz

Ensure to add /usr/local/go/bin to your PATH after using this method to install Go. You can do this by adding the line below to your ~/.profile or ~/.bash_profile file.

~/.profile
export PATH=$PATH:/usr/local/go/bin

You may need to run source ~/.profile or source ~/.bash_profile to apply your changes immediately before the go command becomes available to use.

macOS

The easiest way to install Go on macOS is by using Homebrew:

$ brew install go

Alternatively, you can download the package file, and follow the prompts to install the Go tools.

Windows

Download the MSI installer, open it and follow the on screen instructions to install Go on your machine. By default, the Go tools will be installed in C:\Go.

Test your installation

To check whether you have Go installed correctly, open a terminal and enter the command below:

$ go version

It should output the version of Go you have installed as well as your system architecture. This is the output it printed on my machine for example:

Sample output
go version go1.14.1 linux/amd64

If you don’t see this information, and you’re on Windows, check that Go is in your PATH system variable. Definitely make sure to troubleshoot your installation and get it working before proceeding.

Basic editor setup

Go programs are written in simple UTF-8 text files with the .go extension so you can use any code editor to program in Go. However, I recommend using VSCode as it has strong Go support with the help of the vscode-go plugin.

Once you install the plugin, it will provide formatting and intelligent code completion for you. Make sure to leave the formatting on, and respect the formatting rules it uses by default even if you have your own preferences.

The reason for this is that the idiomatic way to format all Go code is by using the gofmt tool which the vscode-go plugin leverages by default. Straying away from the rules used by gofmt is frowned upon in the Go community.

Write your first Go program

Now that you’ve installed Go and set up your editor, you can proceed to write your first Go program. Traditionally, the first program you write when learning a new language will be one that prints the text “Hello, world!” to the screen, so we’ll do the same here.

Create a project directory for your code

The first step is to create a new directory to store your Go code. In the past, it was compulsory to create your Go projects inside your GOPATH which is an environmental variable that determines where Go should read and download all the source files it will use for compiling your project. The GOPATH is assumed to be $HOME/go on Unix systems and %USERPROFILE%\go on Windows by default, although you can change it to some other directory.

As of Go v1.11, this is no longer necessary due to the introduction of Go modules which we’ll discuss shortly. You can now create your Go projects anywhere on your filesystem and it won’t matter to the Go compiler.

You can create a directory for your project and change into it using the commands below:

$ mkdir hello-world
$ cd hello-world

Write and run a Go program

Create a new main.go file inside your project directory and open it up in your text editor. Enter the code below into the file and save it.

main.go
package main

import "fmt"

func main() {
	fmt.Println("Hello, world!")
}

Head over to your terminal window and enter the following command to compile the program:

$ go build main.go

This will produce a main binary file in your project directory. To run the program, enter ./main in the terminal. It should print the text Hello, world! to your screen. If it did, congratulations! You are now officially part of the Go community.

Screenshot showing output of building and running the Go program

Review of the Hello World program

Let’s review the above program in detail so you can understand it better. Here’s the first line:

package main

Every Go source file belongs to a package. A package is nothing more than a directory containing one or more source files or other Go packages. To declare a file as part of a package, we use the package <packagename> syntax which must be the first line in the file.

The main package is special in Go. It indicates that the program should produce an executable binary, and also serves as the entry point for every executable Go program.

Inside the main package, a special main function must be declared that takes no arguments and returns no value. This function will be invoked automatically when the program runs.

func main() {

}

The above code defines a function in Go. The func keyword is used to create a new function with a name (main in this case) and any parameters within the parenthesis. The function body is also wrapped in curly braces {}. Go requires that the opening curly brace must be on the same line as the function declaration, otherwise the code will fail to compile.

Inside the main function, we have the following code:

fmt.Println("Hello World!")

The fmt package comes from Go’s standard library, and it exports several methods related to formatting and printing output or reading input from various sources. The Println method for example, outputs the provided string to the screen and adds a newline at the end.

Before we can use methods from the fmt package, we need to bring it into scope. That is what the following line is about:

import "fmt"

Compiling and running Go programs

Unlike dynamic languages such as JavaScript or Python, Go programs must be compiled into a binary before they can be executed. The way you compile a Go program is by using the go build command and passing it a source file or an import path:

$ go build main.go

If compilation is successful, the command will not emit any output on the screen. But you will discover that a binary executable (main) has been produced in your project directory. This is what you need to execute to run the program.

$ ./main

There is another way to compile and run a Go program with a single command:

$ go run main.go

This will compile the program and run it immediately without producing a binary in your project directory. Note that go run is really only meant to be used for small programs, which generally need just a single file. For non-trivial programs, using go build && ./<executable> is the recommend way to build and run Go programs.

Screenshot showing output of go run main.go

A short introduction to Go modules

A module is a collection of related Go packages that are released together as one entity. Typically, each Go project consists of a single module that lives at the root of the project folder and is defined by a go.mod file. This file is where the project’s module path is defined as well as any dependencies needed to build the project.

To create a new module, use the go mod init command at the root of your project. You need to pass the import path of the project (usually the URL of your project’s repository without the scheme). Even if you do not plan to publish your code, it’s still a good habit to organise it as if you will do so in the future.

$ go mod init github.com/ayoisaiah/hello-world
Screenshot showing the output of go run main.go

If you build and run your project, it should work just the same as before. The difference is that including third-party dependencies in your project is now possible because Go now knows how to track the dependency versions that your module is using. Without initialising a go.mod file, any attempt to build a project with third-party dependencies will fail with an error.

We’ll continue to explore some more features of Go modules in subsequent tutorials. However, if you’re keen to dig deeper, check out this series of posts on the subject on the official Go blog.

Conclusion

In this article, we discussed why Go was developed and what problems it solves. We also considered some of the common uses of the language and why you should learn it. Then we installed it and proceeded to write, build and execute our first program in the language.

The next tutorial will take you through a more interesting exercise of building a guessing game which will introduce you to several new concepts that should make you more comfortable with reading and writing Go code.

Thanks for reading, and happy coding!