Go version 1 series
Well Executed
![© Lead Image CC BY-SA 3.0 © Lead Image CC BY-SA 3.0](/var/linux_magazin/storage/images/issues/2015/174/go-language/golang_gopher_ccby-sa3.0.png/648903-1-eng-US/Golang_Gopher_CCBY-SA3.0.png_medium.png)
© Lead Image CC BY-SA 3.0
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 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.
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 codepkg/
for object filesbin/
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.
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
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](https://www.linux-magazine.com/var/linux_magazin/storage/images/media/linux-magazine-eng-us/images/misc/learn-more/834592-1-eng-US/Learn-More_medium.png)
News
-
NVIDIA Released Driver for Upcoming NVIDIA 560 GPU for Linux
Not only has NVIDIA released the driver for its upcoming CPU series, it's the first release that defaults to using open-source GPU kernel modules.
-
OpenMandriva Lx 24.07 Released
If you’re into rolling release Linux distributions, OpenMandriva ROME has a new snapshot with a new kernel.
-
Kernel 6.10 Available for General Usage
Linus Torvalds has released the 6.10 kernel and it includes significant performance increases for Intel Core hybrid systems and more.
-
TUXEDO Computers Releases InfinityBook Pro 14 Gen9 Laptop
Sporting either AMD or Intel CPUs, the TUXEDO InfinityBook Pro 14 is an extremely compact, lightweight, sturdy powerhouse.
-
Google Extends Support for Linux Kernels Used for Android
Because the LTS Linux kernel releases are so important to Android, Google has decided to extend the support period beyond that offered by the kernel development team.
-
Linux Mint 22 Stable Delayed
If you're anxious about getting your hands on the stable release of Linux Mint 22, it looks as if you're going to have to wait a bit longer.
-
Nitrux 3.5.1 Available for Install
The latest version of the immutable, systemd-free distribution includes an updated kernel and NVIDIA driver.
-
Debian 12.6 Released with Plenty of Bug Fixes and Updates
The sixth update to Debian "Bookworm" is all about security mitigations and making adjustments for some "serious problems."
-
Canonical Offers 12-Year LTS for Open Source Docker Images
Canonical is expanding its LTS offering to reach beyond the DEB packages with a new distro-less Docker image.
-
Plasma Desktop 6.1 Released with Several Enhancements
If you're a fan of Plasma Desktop, you should be excited about this new point release.