Install and Setup
If you're thinking about engineering the next big dotcom application then you should seriously consider using Go!!
The Go Programming Language is without doubt one of the hottest languages to learn, particularly in this cloud native era. More and more companies are adopting Go to engineer highly performant, stable and maintainable applications. Popular projects such as Docker, Kubernetes, Terraform, Etcd, Istio, InfluxDB have all been built successfully using Go!!
This introductory level training course is designed to bring you quickly up to speed with the many key features that the Go programming language provides. You'll also learn how to setup your own Go development environment - consisting of the Go toolchain, Visual Studio Code, and several related Go based extensions - all to ensure that you are able to be productive writing your own source code.
We’d love to get your feedback on this course, so please give it a rating when you’re finished. If you have any queries or suggestions, please contact us at email@example.com.
By completing this course, you will:
- Learn about what makes Go a great language
- Learn how to install the Go toolchain
- Learn how to setup Visual Studio Code to edit and debug Go programs
- Learn how to work with the Go Playground to test and run snippets of Go code
- Learn and understand the basic Go language syntax and features
- Learn how to use the Go tool chain commands to compile, test, and manage Go code
- And finally, you’ll learn how to work with and manage Go modules for module dependency management
This course is intended for:
- Anyone interested in learning the Go Programming Language
- Software Developers interested in using Go to compile and test Go based applications
- DevOps practitioners looking to learn about Go to support Go based applications
To get the most from this course, you should have at least:
- A basic understanding of software development and the software development life cycle
All sample Go source code as used and demonstrated within this course can be found here:
- [Jeremy Cook] Welcome back. Before I begin reviewing the Go language syntax, I'll quickly review and demonstrate several of the more important Go tools and subcommands that were installed as part of the Go installation. Many of the useful utilities are invoked as subcommands off the main Go command.
Let's now see this in action. Jumping into the terminal, if I invoke Go by itself, you can see all of the available subcommands. You will likely use many of these commands day in day out when developing and maintaining Go code. Let's now take a closer look at some of them.
For starters, the "go env" command can be executed to display information about the current Go operating environment. Important Go environment variables are the GOPATH and GOROOT. I've previously stated what these represent, but it's important and worthwhile stating again. GOROOT is a variable that defines where your Go SDK has been installed to, and GOPATH is a variable that defines the root of your workspace, and will be the location where a lot of 3rd party source code, packages, and/or modules will be found. The go env output can be filtered to just the values that you are interested in by passing in the name or names as arguments. Running the command "go help environment" will display the documentation as to the meaning of each variable.
The "go doc" command is super helpful when you want to consult the standard library documentation for a particular package. For example, you can bring up the documentation for the math package by running the command go doc math. This displays all of the packages exported functions and constants, and is useful to display the signatures for the functions. You can drill down into the documentation for a particular function. For example, let's take a closer look at the Pow10 function, we can do so by running the command go doc math.Pow10. Here, we can see not only the function signature, but also an explanation of the function's behavior and how it should be used. After each coding iteration is completed, you'll want to execute the code to see how it behaves at runtime.
The "go run" command is a convenient fast way to both compile and then execute immediately, allowing you to observe and use the running application. It is essentially a shortcut for compiling and running in one hit. "Go build" performs just the compilation phase, generating a binary as its output if the compilation succeeds. "Go build" will create an executable binary if the source code contains a main package with a main function declared within it. Typically, you'll call "go build" with the -o parameter which is used to explicitly name the executable.
The "go build" command provides two very cool features. The first being that it compiles down everything into a single executable binary. And the second is that it can perform cross-compilation. By default, go build will compile for the current operating system and architecture. Using various flags you can recompile the same source code for other operating system and architecture combinations. For example, recompiling the current project for Linux on AMD64 architecture is as simple as running the following build command. Likewise, recompiling for Windows on AMD64 is achieved by executing the following build command. To see the full list of supported operating systems and architectures, you can run the command: go tool dist list. Go encourages you to unit test all your source code by integrating unit testing capabilities directly within the go toolchain.
The "go test" command can be invoked with various options to either run tests in the current directory, in a specific directory, or across all directories recursively. Additional filtering can be used to run specific unit tests only. For example, you can use the run flag with a regular expression to target matching named unit tests. The previous command used the -v flag to enable verbose mode to see more detailed information. Inevitably, you will at some time likely author go code that utilizes a third party go module. Third party go modules are automatically pulled down whenever you execute the go run or go build command if they are not already local. Sometimes however, you may want to retrieve a particular version. In this case, you can use the "go get" command, which takes the path to the module plus a semantic version. For example, to retrieve the Googles UUID module and version 1.1.0 use the following go get command. Or instead, you can use a commit id. This time lets download version 1.0.0, which has the commit id of d460ce9. If we now run the command "go list -m all", we'll see all of the dependencies that the current project is configured with. This will also now be reflected with a go.mod file:
The go mod command is used to manage and maintain modules. Modules are used to collect multiple related packages together. Creating your own module can be accomplished with the command "go mod init" with the name and location of the module. For example, to recreate the godemo module, I can delete the go.mod and go.sum files. And then run the command: go mod init github.com/cloudacademy/godemo. This will recreate the go.mod file as seen here. Let's examine its contents. Next, I'll call the go get command to re-pull down any module dependencies. Reexamining the go.mod file, you can see that it is now populated with a required module dependency. This will have been pulled down and stored into the GOPATH. We can confirm this by running the following command. We can also run the command "go list -m all" to display all of the dependencies for this project. We can also run the command "go mod why -m", for example, on the UUID module to get an understanding of why it is considered a dependency within the project and what is actually depending on it.
Other interesting commands that are useful for managing modules are: "go mod verify", used to verify the integrity of downloaded modules ensuring that they haven't been modified. This consults the go.sum file which contains cryptographic checksums of all downloaded modules. "go list -u -m all", used to list out all dependent modules and whether an updated version exists and if so, what the latest semantic version number is. "go mod tidy", used to prune out any required module declarations from the go.mod file if the module dependency is no longer used within the project source code anywhere.
The gofmt and "go fmt" tools can be used to reformat source code to what Go considers best practices. This helps to ensure consistency is maintained across your code base. For example, if I were to add some redundant white space to the main.go file and save it, I could then run the command: gofmt -s -d main.go. This will reformat the code showing just the differences but not save the changes. The -s flag performs simplifications on the code. The -d flag performs a diff to highlight before and after. The absence of the -w flag allows you to examine the changes before applying them to the disk. Extending the same command with the -w flag will cause the changes to be saved. To perform this command recursively, use the following command: gofmt -s -d -w . The go fmt ./... is a shortcut wrapper over the gofmt tool, and will perform the same reformatting recursively across the entire project, saving all updates to the disk in one hit.
The "go vet" command is used to perform a static analysis across your source code. It can be used to detect and report on code that although compiles may be considered problematic. For example, it can detect issues such as unreachable code. go vet can be called on single files, all files in the current directory, or across the entire project. As an example, if I were to add the following bad function implementation to the util calc.go file and then compiled it, it should compile even though it contains unreachable code, as it does. Let's now run go vet on it, and as you can see the static analysis has flagged the unreachable code.
Okay, that completes this lecture in which I documented and reviewed many of the commands within the Go tool chain. Go ahead and close it and I'll see you in the next one.
Jeremy is the DevOps Content Lead at Cloud Academy where he specializes in developing technical training documentation for DevOps.
He has a strong background in software engineering, and has been coding with various languages, frameworks, and systems for the past 20+ years. In recent times, Jeremy has been focused on DevOps, Cloud, Security, and Machine Learning.
Jeremy holds professional certifications for both the AWS and GCP cloud platforms.