A Quick Introduction to Go
Imagine that you are a developer and you want to create a command-line utility. Similarly, imagine that you have a REST API and you want to create a RESTful server that implements that REST API. The first thought that will come to your mind will most likely be which programming language to use.
The most common answer to this question is to use the programming language you know best. However, this book is here to help you consider Go for all these and many more tasks and projects. In this chapter, we begin by explaining what Go is, and continue with the history of Go, and how to run Go code. We will explain some core characteristics of Go, such as how to define variables, control the flow of your programs, and get user input, and we will apply some of these concepts by creating a command-line phone book application.
We will cover the following topics:
- Introducing Go
- Hello World!
- Running Go code
- Important characteristics...
Introducing Go
Go is an open-source systems programming language initially developed as an internal Google project that went public back in 2009. The spiritual fathers of Go are Robert Griesemer, Ken Thomson, and Rob Pike.
Although the official name of the language is Go, it is sometimes (wrongly) referred to as Golang. The official reason for this is that go.org was not available for registration and golang.org was chosen instead. The practical reason for this is that when you are querying a search engine for Go-related information, the word Go is usually interpreted as a verb. Additionally, the official Twitter hashtag for Go is #golang.
Although Go is a general-purpose programming language, it is primarily used for writing system tools, command-line utilities, web services, and software that work over networks. Go can also be used for teaching programming and is a good candidate as your first programming language because of its lack of verbosity and clear...
Hello World!
The following is the Go version of the Hello World program. Please type it and save it as hw.go
:
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello World!")
}
Each Go source code begins with a package
declaration. In this case, the name of the package is main
, which has a special meaning in Go. The import
keyword allows you to include functionality from existing packages. In our case, we only need some of the functionality of the fmt
package that belongs to the standard Go library. Packages that are not part of the standard Go library are imported using their full internet path. The next important thing if you are creating an executable application is a main()
function. Go considers this the entry point to the application and begins the execution of the application with the code found in the main()
function of the main
package.
hw.go
is a Go program that runs on its own. Two characteristics make hw.go
an autonomous...
Running Go code
You now need to know how to execute hw.go
or any other Go application. As will be explained in the two subsections that follow, there are two ways to execute Go code: as a compiled language using go build
or as a scripting language using go run
. So, let us find out more about these two ways of running Go code.
Compiling Go code
In order to compile Go code and create a binary executable file, you need to use the go build
command. What go build
does is create an executable file for you to distribute and execute manually. This means that the go build
command requires an additional step for running your code.
The generated executable is automatically named after the source code filename without the .go
file extension. Therefore, because of the hw.go
source file, the executable will be called hw
. In case this is not what you want, go build
supports the -o
option, which allows you to change the filename and the path of the generated executable file. As an...
Important characteristics of Go
This big section discusses important and essential Go features including variables, controlling program flow, iterations, getting user input, and Go concurrency. We begin by discussing variables, variable declaration, and variable usage.
Defining and using variables
Imagine that you wanted to perform some basic mathematical calculations with Go. In that case, you need to define variables to keep your input and your results.
Go provides multiple ways to declare new variables in order to make the variable declaration process more natural and convenient. You can declare a new variable using the var
keyword followed by the variable name, followed by the desired data type (we will cover data types in detail in Chapter 2, Basic Go Data Types). If you want, you can follow that declaration with =
and an initial value for your variable. If there is an initial value given, you can omit the data type and the compiler will guess it for you.
This...
Developing the which(1) utility in Go
Go can work with your operating system through a set of packages. A good way of learning a new programming language is by trying to implement simple versions of traditional UNIX utilities. In this section, you'll see a Go version of the which(1)
utility, which will help you understand the way Go interacts with the underlying OS and reads environment variables.
The presented code, which will implement the functionality of which(1)
, can be divided into three logical parts. The first part is about reading the input argument, which is the name of the executable file that the utility will be searching for. The second part is about reading the PATH
environment variable, splitting it, and iterating over the directories of the PATH
variable. The third part is about looking for the desired binary file in these directories and determining whether it can be found or not, whether it is a regular file, and whether it is an executable file. If the...
Logging information
All UNIX systems have their own log files for writing logging information that comes from running servers and programs. Usually, most system log files of a UNIX system can be found under the /var/log
directory. However, the log files of many popular services, such as Apache and Nginx, can be found elsewhere, depending on their configuration.
Logging and putting logging information in log files is a practical way of examining data and information from your software asynchronously either locally or at a central log server or using server software such as Elasticsearch, Beats, and Grafana Loki.
Generally speaking, using a log file to write some information used to be considered a better practice than writing the same output on screen for two reasons: firstly, because the output does not get lost as it is stored on a file, and secondly, because you can search and process log files using UNIX tools, such as grep(1)
, awk(1)
, and sed(1)
, which cannot...
Overview of Go generics
This section discusses Go generics, which is a forthcoming Go feature. Currently, generics and Go are under discussion by the Go community. However, one way or another, it is good to know how generics work, its philosophy, and what the generics discussions are about.
Go generics has been one of the most requested additions to the Go programming language. At the time of writing, it is said that generics is going to be part of Go 1.18.
The main idea behind generics in Go, as well as any other programming language that supports generics, is not having to write special code for supporting multiple data types when performing the same task.
Currently, Go supports multiple data types in functions such as fmt.Println()
using the empty interface and reflection—both interfaces and reflection are discussed in Chapter 4, Reflection and Interfaces.
However, demanding every programmer to write lots of code and implement lots...
Developing a basic phone book application
In this section, to utilize the skills you've picked up so far, we will develop a basic phone book application in Go. Despite its limitations, the presented application is a command-line utility that searches a slice of structures that is statically defined (hardcoded) in the Go code. The utility offers support for two commands named search
and list
that search for a given surname and return its full record if the surname is found, and lists all available records, respectively.
The implementation has many shortcomings, including the following:
- If you want to add or delete any data, you need to change the source code
- You cannot present the data in a sorted form, which might be OK when you have 3 entries but might not work with more than 40 entries
- You cannot export your data or load it from an external file
- You cannot distribute the phone book application as a binary file because it uses hardcoded data...
Exercises
- Our version of
which(1)
stops after finding the first occurrence of the desired executable. Make the necessary changes towhich.go
in order to find all possible occurrences of the desired executable. - The current version of
which.go
processes the first command-line argument only. Make the necessary changes towhich.go
in order to accept and search thePATH
variable for multiple executable binaries. - Read the documentation of the
fmt
package at https://golang.org/pkg/fmt/.
Summary
If you are using Go for the first time, the information in this chapter will help you understand the advantages of Go, how Go code looks, and some important characteristics of Go such as variables, iterations, flow control, and the Go concurrency model. If you already know Go, then this chapter is a good reminder of where Go excels and the kinds of software where it is advised to use Go. Lastly, we built a basic phone book application with the techniques that we have learned so far.
The next chapter discusses the basic data types of Go in more detail.
Additional resources
- The official Go website: https://golang.org/
- The Go Playground: https://play.golang.org/
- The
log
package: https://golang.org/pkg/log/ - Elasticsearch Beats: https://www.elastic.co/beats/
- Grafana Loki: https://grafana.com/oss/loki/
- Microsoft Visual Studio: https://visualstudio.microsoft.com/
- The Standard Go library: https://golang.org/pkg/