Go version 1 series

Well Executed

© Lead Image CC BY-SA 3.0

© Lead Image CC BY-SA 3.0

Article from Issue 174/2015
Author(s):

The Go programming language helps programmers avoid the annoying routine and focus on the important stuff.

In 2009, Google launched the Go programming language [1]. An impressive collection of veteran developers worked on Go, including Ken Thompson (one of the inventors of Unix), Plan 9 co-creator Rob Pike, and Rob Griesemer, who previous worked on Google projects such as the Smalltalk variant Strongtalk.

The goal of Go was to create a statically typed language similar to C, but with updated features such as garbage collection and better type safety. In addition to its trademark CSP (Communicating Sequential Processes) [2] concurrency solution, the influences of Limbo [3] and Inferno [4] are evident.

Early versions of Go evolved at a rapid pace, with the code changing so fast that applications written one week would no longer compile in later versions. Finally, in 2012, Go 1.0 was released with the promise that you would be able to compile any code in future versions of the 1.x series. Since then, the focus of the Go developers has been on tools, compilers, and the run time.

Build System

In the beginning, Go did not have its own build system; developers had to call the compiler and linker manually or write makefiles for larger projects, much like C. However, because Go wanted to facilitate the process of developing complex and distributed projects, it needed a superior solution. The go tool provided an easy-to-use build system without any need for configuration. Table 1 lists the most important commands.

Table 1

Important Go Tool Commands

Command

Effect

go build

Checks packages and dependencies and compiles, but does not keep the results: a viability check.

go install

Much like go build, but also installs and keeps the library results to accelerate later compile runs.

go get

Downloads and installs packages and dependencies for the current project.

As mentioned previously, none of these functions needs any configuration; a developer does not need to write makefiles, list the dependencies explicitly, or link to the source code. Two simple principles make this possible: the GOPATH variable (Figure 1), which behaves like PATH and defines workspaces, and package paths, which specify paths to the packages and which must not be the same path as your Go installation.

Figure 1: The GOPATH variable and its paths in a sample project.

GOPATH is an important concept. This variable, determines whether Go finds the source code for the package and where it stores object files. Each workspace comprises three folders:

  • src/ for source code
  • pkg/ for object files
  • bin/ for compiled, executable files

In other words, when the developer runs go build, the build script looks for the source code in $GOPATH/src/, and go install writes files to $GOPATH/pkg/ and $GOPATH/bin/.

All the source code is broken down into packages. Each folder and subfolder in $GOPATH/src/ represents a single package; that is, each piece of source code must reside in such a package for Go to find it.

Unlike Java workspaces, however, a Go workspace does not relate exclusively to a single project. Instead, it references the collection of Go packages and projects (i.e., its own copy of part of the Go universe). Therefore, different projects typically exist in a single workspace. Each package can be accessed via an individual path. Whereas packages in the standard library have very short pathnames (e.g., fmt or net/http), your own packages should have intuitive names that do not collide with names assigned to packages by other developers. For this reason, programmers often use the path by which they access the package on the Internet (e.g., on GitHub [5]: github.com/<user>/<example>).

This pattern is unique, because no one else will have the same username. At the same time, this type of naming convention makes it possible to retrieve the packages automatically off the Internet at a later time.

In Action

The following code exemplifies the file structure and shows the tools in action. To begin, a developer creates the basic structure for a package:

$ export GOPATH=~/go/
$ mkdir -p $GOPATH/src/github.com/<user>/hello

The pathname github.com/<user>/hello assumes that the package will be hosted on GitHub some time in the future. Listing 1 shows the source code of the program, which resides in the $GOPATH/src/github.com/<user>/hello file and is named hello.go. You could use another name (e.g., main.go).

Listing 1

hello.go

 

To compile the project, the developer passes the path into the package and receives an executable file in the current directory as the result. The file is named for the folder with the source code – hello in this example. When you run the program, it says hello in a style familiar to programmers:

$ go build github.com/<user>/hello
$ ./hello
Hello, User.

By using go install instead of go build, the final results end up in the specified $GOPATH/bin/ folder. Apart from this, though, the program behaves in an identical way:

$ go install github.com/<user>/hello
$ $GOPATH/bin/hello
Hello, User.

This slightly modified version of the program in Listing 2 uses an external library to hand over parameters at the command line.

Listing 2

hello.go (Version 2)

 

Although Go includes the flag package in its standard library, this implements the flag rules of Plan 9 [6], and not the GNU rules. The attempt to compile fails, as you can see in Listing 3.This compile fails because the user has simply not downloaded the pflag package yet.

Listing 3

Forgotten Dependencies

 

The go get command shown in the following example can help with this task; it retrieves packages from the Internet and installs them recursively, thus also resolving dependencies. If the developer calls go get first for their own package, the program resolves all of the dependencies (i.e., pflag in this case).

$ go get github.com/<user>/hello
$ go build github.com/<user>/hello
/junk/src $ ./hello
Hello, unknown
/junk/src $ ./hello --name="dear reader"
Hello, dear reader

This workflow scales without problem for hundreds of packages and dependencies. Developers never have to say how exactly the build process needs to run, what version control system they use, or how to download dependencies.

End to All Disputes

As trivial as this might sound, programmers waste a huge amount of time arguing about the correct way to format code. Do you use spaces or tabs? How many spaces do you use? Where do you put the curly brackets? Every developer has their own preferences. This fact of coding life, means learning new guidelines for each new project and each new job.

Go does not have this problem. It comes with the gofmt tool, which formats the code for the developer in the only correct way (Figure 2). It does not offer any options that influence the results, and every Go developer is prompted to use gofmt. This puts an end to discussions about code formatting and means the code is uniformly formatted all over the world, making it easily readable.

Figure 2: The gofmt tool automatically formats the Go code.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Go Programming

    The Go programming language combines type safety with manageable syntax and an extensive library. We take you through a programming example.

  • Meson Build System

    Developers fed up with cryptic Makefiles should take a look at the new Meson build system, which is simple to operate, offers scripting capabilities, integrates external test tools, and supports Linux, Windows, and Mac OS X.

  • Oil Shell

    With its innovative scripting language, Oil, the Bash-compatible Oil shell aims to make life easier for script developers.

  • Wego

    Other applications have found less complex ways of showing the weather in a terminal, but none is as attractive as Wego.

  • Batsh

    Batsh kills two birds with one stone: Programs written in this language can be compiled both as Linux Bash scripts and Windows batch files.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News