Go tutorial: Get started with Google Go

Go is a concise, simple, safe, and fast compiled language that trades features for speed. Isn’t it time you gave it a try?

Why would you want to use the Go language? Basically, it’s a concise, simple, safe, and fast compiled language with wonderful concurrency features, and it easily handles large projects. It’s also free open source, even though it was originally developed at Google.

According to Rob Pike, one of the designers of the language, “the goals of the Go project were to eliminate the slowness and clumsiness of software development at Google, and thereby to make the process more productive and scalable. The language was designed by and for people who write—and read and debug and maintain—large software systems.”

In accordance with those goals, Go lacks many features of some other prominent languages—and that’s actually a strength. Go is not object-oriented, it doesn’t have header files or forward declarations, it doesn’t have a type hierarchy, it doesn’t have method or operator overloading, it doesn’t have generics, it doesn’t have a virtual machine for a runtime, it doesn’t have exceptions, and it doesn’t have assertions.

On the other hand, what Go has works quite well. It can compile big programs in a few seconds. It has low-overhead coroutines (called goroutines) that can communicate efficiently through channels. It has interfaces and interface composition. In addition, Go supports first-class functions, higher-order functions, user-defined function types, function literals, closures, and multiple return values—in other words, it supports a functional programming style in a strongly typed language.

If you’re dying to request any of the missing features I mentioned above, you might want to read the discussion of language changes in the Go language FAQ: The answer is usually “No, because…” In general, the best Go programs are designed from scratch to use Go language features, rather than translated literally from other languages that use different abstractions.

Install Go

The short instructions for installing Go appear in the source repository. You can download binary releases of Go for Windows, MacOS, and Linux or install Go from source. You’ll find instructions for installing Go from source on GitHub.

If you already have Go installed, you should check the current build version at the bottom of https://golang.org/ and then check your installed version from the command line:

$ go version

If your installation is out of date, download and install the current version. Restart any open command prompts (Windows) or terminals. Rerun go version and make sure that the version is what you expected; if not, there may be an older version of Go installed elsewhere that needs to be removed.

(No, I’m not paranoid. I managed to get myself into the situation I described by using Homebrew to install one version and the standard MacOS package to install the next version a month or so later. They install to different locations on the $PATH. Once I figured out what had happened, I was able to uninstall the old version with Homebrew.)

Another installation option, if you want support and indemnification and you are able to pay, is to use ActiveGo.

Once you have the Go compiler and tools installed, you should go through the exercise of compiling and running a Go program, as described in the “Test your installation” section of the install page.

Set up your Go environment

Go programmers typically keep all their code in one workspace, with bin, pkg, and src folders. Within each folder, the projects typically have paths that relate to Git repositories, such as GitHub or GitLab. For example, I keep all my Go language code under ~/work, and set my GOPATH environment variable to $HOME/work. The path to my “hello.go” source code folder is $GOPATH/src/github.com/meheller/hello.

I also add the GOPATH/bin directory to my path, for convenience in running Go programs from any directory:

export GOPATH=$HOME/work
export PATH=$PATH:$(go env GOPATH)/bin

The Go language utilities will install in GOPATH by default, so putting the GOPATH/bin directory on the path also makes it easier for you and Go-aware editors and IDEs to find them. You can install most of the utilities with $go get <repo-path> once you know which ones you need and their repository paths. The repositories are usually easy to find with a Google search. In some cases, an editor plug-in for Go will install the utilities (e.g. gocode) automatically.

If you don’t set it yourself, GOPATH defaults to $HOME/go on Unix and MacOS and %USERPROFILE%/go on Windows.

Go language tools, editors, and IDEs

Several Go utilities are installed as part of the package with the compiler. Others can be installed with the go get command. The most-used Go command-line utilities are listed below.

The usual way of calling most of these commands is as subcommands of go, for example go fmt. Others need to be called via the go tool subcommand. On my installation, go tool returns the following list of known tools:

$ go tool
addr2line
asm
buildid
cgo
compile
cover
dist
doc
fix
link
nm
objdump
pack
pprof
test2json
tour
trace
vet

These tools are documented as part of the full list of Go commands. By the way, make sure your GOPATH is set before adding any Go tools, or any Go editor plug-ins that use Go tools.

The Go repository has lacked any editor or IDE support since version 1.4, but there are plenty of both that know about Go, either out of the box or with add-in modules. I discussed many of these in a 2017 InfoWorld article; there’s also an unofficial list maintained by the Golang community.

go goland IDG

The GoLand IDE for Go. 

My favorite Go language IDEs are GoLand (shown above; renamed from Gogland since I wrote the article in 2017) and Komodo. Both are paid products with free trials.

You’ll want to install Delve for Go debugging. On MacOS, you may also need to add the command line utilities to Xcode, and possibly add a soft link to debugserver, as described in the June 5 comment in the Delve issues list. Running xcode-select --install will also fix issues about finding debugserver, albeit in a brute force manner.

My favorite Go-aware editors with GUIs are Atom and Visual Studio Code; both are free. If you choose Atom, consider adding the go-plus and go-debug packages; if you choose Visual Studio Code, consider adding vscode-go.

If you’re a hardcore Vim or Emacs user, then by all means stay with what you know—not that I could even pry your editor from your cold, dead hands. Vim-go adds Go language support for Vim, and go-mode adds Go language support for Emacs.

A Tour of Go

You can learn quite a bit by going through “A Tour of Go,” either online or offline. Assuming that you completed the local installation of the Go compiler and tools, you can install the tour to run locally by running these two commands:

$ go get golang.org/x/tour/gotour 
$ gotour

The second line should start a web server and open a browser window. This will look exactly like the online tour, but might run a little faster because it builds and runs the code samples on your own machine. Press Ctrl-C in the command window to stop the server when you’re done.

The tour is divided into three sections. I want you to go through the whole tour, including the quizzes, but I’ll summarize each section below as an overview, and ask you some questions. I provide the answers to my questions at the end of the article (no peeking!). 

Go language basics

go basics

Go Basics Lesson 1

IDG
go lesson 1 IDG

Question 1. In this example, there are three packages. What are they, and how are they being used? Why does the program always return the same number even though there’s a rand function?

Note that I haven’t called out Lesson 2. Don’t skip lessons just because I haven’t commented on them.

Go Basics Lesson 3

go lesson 3 IDG

If you run this example, you’ll see error messages:

prog.go:9:14: cannot refer to unexported name math.pi 
prog.go:9:14: undefined: math.pi

Question 2. Why the errors? How can you fix the program?

Go Basics Lesson 4

go lesson 4 IDG

Question 3. Compare this declaration to the equivalent in C. What is different?

Go Basics Lesson 8

go lesson 8 IDG

Question 4. Why doesn’t this program throw any errors?

Go Basics Lesson 10

go lesson 10 IDG

Question 5. What is the type of k? Why? If the type is not obvious, look at Lesson 11 to find out how to display it.

Go Basics Lesson 12

go lesson 12 IDG

This lesson answers the question I asked in Lesson 8.

Go Flow Control Lesson 1

go flow control 1 IDG

Question 6. How is this different from the for loop in your favorite language? Do you think the other looping constructs in your favorite language are necessary? Does the additional information in the next three lessons change your mind?

Go Flow Control Lesson 7

go flow control 7 IDG

Before running this program, desk check it and write down what you think it will print. Run the program. Were you correct? If not, what didn’t you understand?

Go Flow Control Lesson 8

go flow control 8 IDG

This is the sort of exercise you might get at the beginning of a whiteboard interview. Time yourself as you work it out. Say what you are thinking as you work through the problem.

Question 7. The rest of the flow control section is important to understand. After going through lessons 9 through 13, explain the Go switch and defer statements in a way that a C, Java, or JavaScript programmer could grok.

Go More Types Lesson 1

go more types 1 IDG

Before running this program, desk check it and write down what you think it will print. Run the program. Were you correct? If not, what didn’t you understand?

How do you feel about Go having pointers but not pointer arithmetic?

Work through the More Types section until you get to the exercise in Lesson 18. Question 8. What did you learn about Go arrays and slices? Now complete the exercise.

Continue through the exercise in Lesson 23.

Question 9. Explain a Go map. Why would you want to use one?

Finish the More Types section.

Question 10. Can Go be used as a functional programming language, despite being compiled? When and why would you use closures?

Go methods and interfaces

go methods interfaces IDG

Go through all 25 lessons in this section starting with https://tour.golang.org/methods/1.

Question 11. When you’re done, explain how Go’s use of methods and interfaces is different from C++ classes. Which do you like better? Why?

Go concurrency

go concurrency IDG

The goroutine is one of the defining features of Go for concurrency. In the first lesson in the concurrency section, try to desk check the program (below) and write down what you think it will print.

go concurrency 1 IDG

Run the program. Were you correct? Explain what actually happens, and why.

Channels are the way to implicitly synchronize goroutines. In the next lesson (below), again try to desk check the program before running it.

go concurrency 2 IDG

Question 12. Why is there only one channel in this example, even though there are two goroutine calls?

The select statement lets a goroutine wait on multiple communication operations. What is the order in which statements run in the program below?

go concurrency 5 IDG

The exercise on equivalent binary trees is another you might encounter in a whiteboard interview. Time yourself and explain your thinking as you implement a solution. Similarly, do the exercise on implementing a web crawler as though you were in an interview.

Answers to Go questions

Answer 1. Packages are designated by the package statement for the current program, and by the import statement for external packages being used. In this simple program, main is the program’s own package, and it is importing fmt so that it can print, and math/rand so that it can generate a random number.

The various methods in rand rely on clock time to generate random numbers, but the time is fixed in the gotour environment. As a follow-up exercise, find the package and method that reports the time (hint: look here if you get stuck), and use it to print the current time. Run this multiple times in the gotour environment, and also build the program locally and run it multiple times on your own machine.

Answer 2. Exports in Go must always be capitalized, and the language is case sensitive. math.Pi is the correct method.

Answer 3. In C/C++ variable declarations follow the form <type> <variable list> (e.g. int i, j, k;), whereas in Go the type goes after the variable name and can be omitted as long as the type can be inferred. In C/C++ the return type precedes a function name, whereas in Go it comes after the function parameter list and before the function body. In C/C++, trailing semicolons are mandatory.

Answer 4. It doesn’t throw errors because Go variables that are not otherwise set are initialized to the type’s zero value, e.g. 0 or false. In C/C++, the compiler flags uninitialized variables.

Answer 5. k is an integer, because it was initialized to 3.

1 2 Page 1
Page 1 of 2