Setting up your Go environment

Installing Go is pretty straightforward, you can just download it for your system from the go website. Mac OS users can also use brew, and Windows users can also use chocolatey. In both cases, Go should be installed in the correct location and put into the correct executable $PATH.

For Linux users, once you've downloaded and expanded the tar files, copy it over to /usr/local and set /usr/local/go/bin in your $PATH so you can run go.

Programs written in Go compile down into a single executable file that does not need any other software to run. So you only really need to install Go on the computer that will build the Go code, not necessarily on the computer that will run the final executable.

To test your installation was successful, you can run go version which should print out the version you've just installed.

Your Workspace

You can organise your Go projects as you want, but Go still expects you to have a single place for the libraries you install with go install . You can set this place yourself but it is $HOME/go by default. Either way, it's important to explicitly state where this is in your bash profile.

export GOPATH=$HOME/go
export PATH=$PATH:/$GOPATH/bin

Don't forget to source your .profile to have your updates take effect.

To have a look at all of the environment variables go is aware of, you can run `go env` from your terminal.

$ go env

GOARCH="amd64"
GOENV="/path/to/go/env

What's included, running and building code

Go comes with a ton of stuff off the bat, including a code formatter, a compiler, a linter, a test runner, and a dependency manager.

Here's a simple Hello World program:

//hello.go

package main

import "fmt"

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

If you run go run hello.go, you should see Hello World printed out onto the console, but you won't find a binary next to your hello.go file. This is because go run compiles your code into a binary, but in a temporary folder which it then deletes after it's done executing your code. This makes it handy to use it for scripting or testing things out.

To create an executable, run go build hello.go. The binary name will by default match the file or package name. You can specify the name or location using the -o flag: go build -o my_custom_name hello.go.

Installing other peoples code

Go uses go install to install third-party software. However, the way Go stores and distributes third-party projects is a little different to other languages, like JavaScript with it's NPM registry. There's no central registry with Go. Instead, projects are shared by their source code and compiled on your machine when you run go install. The command takes an argument which is the location of where the source code's repository is and the version of the code you want. It then downloads, compiles, and installs it for you.

As an example, there's a tool called Hey for load testing HTTP servers. You can install it as follows:

go install github.com/rakyll/hey@latest

This will pull the source code down, compile it for you and turn it into an executable, which you can then run as `hey`:

hey https://golang.org

Formatting

Go has a specific way of formatting code that is built-in as part of the language. Unlike most languages that offer flexibility in how you lay your code out, Go has standardised formatting that makes it easier to write, but also easier to manipulate your source code using external tooling.

It also prevents developers from disagreeing on what the "better" way to write their code is. For example, Go uses tabs to indent and you can't choose to write your function's opening brace on the next line like you can in some other languages, it'd actually give you a syntactical error.

Go comes with the command fmt which formats your code for you into this standardised way.

The semicolon insertion rule

Go requires a semicolon at the end of each statement, but the developers themselves don't put them in, the compiler does.

It follows a simple rule, putting a semicolon at the end of a line if the last item is one of the following:

  • An identifier (e.g. int, float64)
  • A basic literal (e.g. 5, "hello")
  • One of the tokens: "continue", "break", "fallthrough", "return", "++", --", "}", ")"

This simple rule makes the Go compiler faster and simple but also enforces a programming style.

Linting and scanning your code for bugs

The tool golint tries to make sure your code matches the Go style guidelines. It highlights things you could change and gives you suggestions, and its a good idea to take them onboard since Go developers expect code to look a certain way. But it's not completely accurate and can give false negatives and positives.

When it comes to catching errors like passing the wrong number of variables to a function or unused variables, that's what the tool go vet is used for.

Since there are many other tools that you can also run to check code style and find bugs, it can be unruly to run them all individually. You can run multiple tools together with golangci-lint. It runs golint, go vet, and a list of other code quality tools. If you don't agree with all of the suggestions it gives you, you can configure which you want to run and what files they should run on by adding a file called .golangci.yml. Then you can run it as usual with golangci-lint run.

The Go Playground

The Go Playground is a website that gives you a place to quickly try out Go code, similar to Python and Node command-line environments.

This post is some of my notes on Go, the resources I've used can be found below.

Resources

Learning Go - Jon Bodner

Effective Go - Golang

Golang Code Review Comments