📄 Page
1
(This page has no text content)
📄 Page
2
Go Faster Join the thriving community of skilled Go developers! Ollie Phillips This book is for sale at http://leanpub.com/gofaster This version was published on 2023-04-18 This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and many iterations to get reader feedback, pivot until you have the right book and build traction once you do. © 2022 - 2023 Ollie Phillips
📄 Page
3
Tweet This Book! Please help Ollie Phillips by spreading the word about this book on Twitter! The suggested tweet for this book is: Go Faster is helping me to learn Golang! The suggested hashtag for this book is #GoFaster. Find out what other people are saying about the book by clicking on this link to search for this hashtag on Twitter: #GoFaster
📄 Page
4
Contents Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 About this book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Before you begin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Chapter 1 - Introduction to Go . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.1 Why Go? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2 Language semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.3 Visibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.4 Comments and documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Chapter 2 - The Go command line interface (CLI) . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.1 Version information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.2 Environment information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.3 Module and workspace management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.4 Format your code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.5 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.6 Cleanup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.7 Downloading packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.8 Running a program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.9 Building your program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.10 Building for other operating systems and architectures . . . . . . . . . . . . . . . . . . . 15 Chapter 3 - Structure of a Go program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.1 Packages and importing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.2 Main and Init functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.3 Developing a package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Chapter 4 - Project organisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.1 The internal folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.2 The cmd folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.3 The pkg folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 4.4 Wrapping it up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
📄 Page
5
CONTENTS Chapter 5 - Dependency management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 5.1 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 5.2 Workspaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 5.3 Vendoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Chapter 6 - Variables and constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 6.1 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 6.2 Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 6.3 Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 6.4 Variable semantics. Pointers and values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 6.5 Value initialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Chapter 7 - Data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 7.1 Basic types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 7.2 Aggregate types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 7.3 Reference types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 7.4 Interface types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 7.5 Creating custom types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 7.6 Converting between types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 Chapter 8 - Managing program flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 8.1 Control structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 8.2 Error handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 8.3 Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 Chapter 9 - Digging deeper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 9.1 Developing with functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 9.2 Memory management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 9.3 Using receivers with custom types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 9.4 Working with interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 9.5 Type assertion and reflection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 9.6 Introducing Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Chapter 10 - Concurrency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 10.1 Goroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 10.2 Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 10.3 Blocking execution with waitgroups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 10.4 Sharing variables using mutexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 10.5 Communicating with channels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 10.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 Chapter 11 - Quality Assurance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 11.1 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 11.2 Benchmarking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
📄 Page
6
CONTENTS 11.3 Profiling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
📄 Page
7
Preface When I started learning Go I was productive with the language fairly quickly. After only a short time I could build fast, safe and stable applications which could run anywhere. Before long I was choosing Go in preference to PHP and Node JS - the other languages I’d been developing with - whenever possible. I continued my journey with Go and learned more as I went, but often, I’d find myself in a bind - Golang wouldn’t do what I wanted it to. I’d find workarounds sure, but they often seemed clunky. As I tackled more advanced problems this happened more frequently and at times it seemed like I couldn’t achieve what I wanted with Go at all! After facing many of these challenges, I realised the actual problem wasn’t with Go, but with my knowledge. For one thing, I found I sometimes didn’t understand how Go wanted me to solve a problem - in the idiomatic ‘Go’ way. Other times, I discovered I had missed some of the more nuanced detail about a topic, which on the surface had appeared straightforward. In a nutshell, I had quickly acquired a core of knowledge about Go - enough to write programs - but I had limited understanding of what was happening under the hood when the compiler took my code off me and ran it. So I decided to try cementing my understanding by teaching Go to others via a weekly Blog and on-site training sessions under the GolangAtSpeed¹ brand. Both aimed to discover and expose what I called “the longtail of Go”: the less obvious parts, the quirky idioms and the gotchas, the things that may catch other developers out too. Covid-19 brought a premature end to the on-site training and the blog mostly fizzled out due to me jumping back into contract Go development at a time of uncertainty. But, I promised myself (and some blog readers) that I’d write a book on the same theme and, almost three years later, here it is! Before you jump into the book itself, I want to thank you for purchasing it. I sincerely hope you enjoy it and get much value from it. I also hope you enjoy your journey with Go as much as I have my own, and that my book does indeed help you get there faster! Finally, my learning journey is not yet complete, I’m simply sharing what I know in Go Faster because I think it may help others. So, if you have any feedback or spot any mistakes, please do reach out to me. In doing so you’ll help me improve the book for others who follow you! Best wishes, Ollie ¹https://golangatspeed.com
📄 Page
8
About this book Go Faster is a book for those wanting to learn the Golang programming language. Though many great books have been published on this subject with the same aim, Go Faster takes a slightly different approach. For starters, it recognises that Go is a relatively simple language with just 25 keywords and that most developers do not struggle to learn its limited syntax. It acknowledges that most readers will be able to set up a Golang development environment using one of the operating system-specific binaries, without needing detailed instruction. It recognises that most readers will have a basic level of programming knowledge already - possibly even prior experience with Go - but that that knowledge may differ, depending on their route into programming and the languages they have used to-date. The examples in Go Faster are simple by design. There are no real world or useful applications, instead, all the non-essential code is stripped away to help the user see the principles being demonstrated and grasp the concepts. Go Faster is designed to assist developers coming from object-oriented programming. It elaborates in areas which can confuse since the Go programming paradigm is different than that of OOP. And like Go itself, Go Faster is opinionated with its semantics. The book also covers features which are relatively new to the language. Features that many developers, even experienced ones, may not yet be familiar with, and many existing texts may not yet explore, such as Generics and Workspaces. Finally, Go Faster reflects the author’s own journey learning Go and is laid out accordingly. Not as an A-to-Z style reference, but in a way that should enable understanding earlier, laying solid building blocks on which the reader can progress. If the author was learning Go again, this is the way they would structure their learning path, and hopefully, it is this structure which helps users at all levels gain a solid understanding of Go, quickly.
📄 Page
9
About the Author Ollie Phillips is a Software Developer based in the United Kingdom. Over the previous 8 years, he has worked with Go in various domains including Finance, Health, Learning Management and Cloud Automation. Most recently he was building tooling in Go for the Morpheus Cloud Management Platform. He is also the author of the GolangAtSpeed² substack blog and is passionate about Go and helping others get productive with it. ²https://golangatspeed.com/
📄 Page
10
Before you begin Some pointers to help you get the most from Go Faster Go Playground Throughout Go Faster we use example code which in most cases is also provided as executable snippets on the Go Playground. You can also use the playground to test your code if you don’t have a local development environment. You can find it here: https://go.dev/play/ All the examples, listed by chapter can also be found on Github here: https://github.com/golangatspeed/GoFasterExamples Installing Go If you do want to set up your local environment, you’ll need to download and install a recent version of Go. At the time of writing the latest version is 1.19. You can get a distribution for your operating system here: https://go.dev/dl/ Editing code locally You’ll have more fun writing Go in a text editor which offers Go-specific helper functions such as code completion, formatting and automatic imports. Either Visual Studio Code - with the appropriate plugins - or Goland which has full Go support out-of-the-box, is recommended. There are links to download pages for both applications below. • Visual Studio Code - https://code.visualstudio.com/download • Goland - https://www.jetbrains.com/go/ A word on the code examples Go Faster was written on macOS, so many of the command line examples will contain Mac/Linux- specific syntax. For example, directory paths are Mac/Linux style and not Windows style.
📄 Page
11
Chapter 1 - Introduction to Go In this chapter, we’ll cover some essentials. First, we’ll lay out a quick introduction to Go explaining what makes it attractive as a programming language, then we’ll address some broader Go concepts and terminology that we will make use of as we progress. 1.1 Why Go? Go, or Golang is a programming language developed by a team at Google. Similar to C (or Clang), it draws inspiration from many other programming languages also. Go is a high-performance language which runs directly against physical machine resources and not on a virtual machine, unlike Java for example. Further, asynchronous programming via concurrency and goroutines can fully utilise the multiple cores of modern CPUs better than many other multi- threaded languages. Go is a compiled language. Your program code is built into an OS-specific executable and not interpreted at runtime. It is statically typed, so types are known - and fixed - at compile time.Memory management in Go is for the most part automatic. Memory allocation is done for us as required, and memory is deallocated when no longer in use via a garbage collection process. Together these traits help to eliminate many common programming errors. Go is opinionated on many things, one of which is formatting. This opinion, together with its simple syntax, results in very readable and clear code. Go has a complete suite of built-in tooling which includes utilities for testing, building, profiling andmore. It is the readable code and powerful tooling which attract many developers to the language. In version 1.11 Go modules were introduced for dependency management and are now the defacto approach. In version 1.18 the hotly debated Generics feature was introduced together with Go workspaces. 1.2 Language semantics Go is not object-oriented although it feels similar at times. Possibly because of that similarity, or more likely familiarity with object-oriented programming (OOP) in general, developers often find themselves conversing about Go using object-oriented semantics which are often not appropriate to Go. You may see and hear terms like instance, object and method - even inheritance - being used in the context of Go code, and while it sort of works, it is mostly incorrect.
📄 Page
12
Chapter 1 - Introduction to Go 6 Better we establish the right Go terminology early on and use it. Especially as the correct semantics can help us understand what Go is doing differently from OOP-based languages. For example, while OOP has inheritance, Go has composition and embedding. There’s an overlap between these approaches but they are not the same thing. Go does not have objects or instances, neither does it have methods in the OOP sense. Instead, we have receivers (or receiver functions), so named because they receive the value (or the address of the value) of the type on which they are bound. While conceptually similar to methods, Go receivers can be bound to any user-defined type, they are not constrained to a class hierarchy. That said, receivers and methods are terms that are used interchangeably in Go. I generally use the term receivers and will do it exclusively throughout Go Faster, purely to break the link with OOP and class-based property access. Like OOP, Go has interfaces - a very powerful aspect of the language when used appropriately - and of course, we have functions. In Go, everything is a value. Even pointers are just a value, that value being the address of another value in memory. There’s no magic, but this concept is core to understanding how to work with values and pointers and avoid some common mistakes. Errors are just values too, Go does not have exceptions. Errors must be checked and handled in your code, which despite being a little verbose and repetitive, contributes greatly to readability and comprehension. So, Go has some specific terminology such as types, receivers and pointers and we should use these. For anything else, it is more correct to refer to it as a value of something and not an instance of something - or indeed an object. There’s quite a lot to unpack there, but don’t worry we will cover all of the above in more detail as we progress. 1.3 Visibility Unlike object-oriented programming, Go does not have the concept of public and private. Instead, it uses the notion of exported and unexported visibility modifiers. Any variable, constant, function, receiver, type or indeed struct field, declared with a lowercase first letter in its name, is considered unexported and cannot be directly accessed outside of its package namespace. The same, when capitalised, is considered to be exported and fully visible to the code that imports the package. The example code below illustrates the principle when applied to types, variables, functions and struct fields. Note the exported struct field in the unexported struct type at line 9 which is a bit odd: an exported field on an unexported struct would appear to be completely redundant.
📄 Page
13
Chapter 1 - Introduction to Go 7 Example 1 - Visibility modifiers 1 package exporting 2 3 type ExportedStruct struct { 4 unexportedField string 5 ExportedField string 6 } 7 8 type unexportedStruct struct { 9 ExportedField string // how is this useful? 10 } 11 12 var ExportedVariable string 13 var unexportedVariable string 14 15 func ExportedFunc() { } 16 17 func unexportedFunc() { } Well, it is redundant when it comes to exporting that field outside of the package because the struct itself is unexported, but you may often see code written like this, simply because there is a need to perform some type of conversion of that struct field into an alternative data format, such as JSON. We call this conversion process marshalling and Go will only marshal exported struct fields when creating the output. Unexported struct fields are ignored. Why does unexported not mean private? Because unexported values can still be made available outside of the package. For example, there is nothingwhich prevents an exported function or receiver from returning an unexported value from the package namespace to the caller. While code like this can be a source of confusion, so it is not recommended practice, it’s perfectly possible to do this. So when building packages for others to use, we should make decisions about exporting and unexporting, not on a need for concealment, but instead as a way of communicating which parts of our package should comprise the API that developers use, and which parts should not. 1.4 Comments and documentation The single-line and multi-line comment styles of Go are probably already familiar and are used in many languages inspired by C. See the example below.
📄 Page
14
Chapter 1 - Introduction to Go 8 Example 2 - Comment styles 1 package main 2 3 func main() { 4 // This is a single-line comment 5 6 /* 7 This is a multi-line comment 8 which spans more than one 9 line. 10 */ 11 } For comments to be useful, they should be concise and precise and must be updated in line with the code. Stale comments which are not maintained with the codebase, detract from the code and may even confuse matters. In Go, comments are especially useful since they are used to generate documentation. Developers write comments inline which then automatically form the basis of their software’s instruction manual. The documentation itself is built from the code comments using a command line tool called Godoc. We’ll cover installing and using the tool shortly, but first, let’s outline some standards to help you get the most from the Godoc tool. 1.4.1 Comment standards 1. All exported functionality of a package is expected to have a comment. The comment should start with the function, variable or type name for which it is written, and should succinctly explain its purpose. Only comments in this format on exported functionality will be used to build documentation. 2. The package itself should include a comment above the package name, which provides an overview of what the package does. This is used in the Overview section of the built documentation. 3. Links can be included in comments via an absolute URL which includes the schema e.g. HTTPS. Relative URLs are ignored. The Godoc tool will parse and include links which meet the requirements in the documentation. 4. Comments separated by a commented blank line will be interpreted as paragraphs and output as such in the package documentation. The example below shows a package with these requirements satisfied. The code is unimportant for the moment.
📄 Page
15
Chapter 1 - Introduction to Go 9 Example 3 - Making the most of comments in documentation 1 // Package user implements functionality for working with users. 2 // 3 // This content will be in a new paragraph. 4 package user 5 6 // User is a representation of a single user 7 type User struct { 8 Name string 9 } 10 11 // NewUser is a factory that allows us to configure the properties 12 // of a new User. 13 // 14 // See https://someurl.com for more information. 15 func NewUser(name string) *User { 16 return &User{ 17 name: name, 18 } 19 } 1.4.2 Installing and using Godoc Godoc is an external package which can be downloaded and installed using the Go tool. Assuming you have installed Go locally, the following command will fetch the latest version of the package and install it in your workspace. 1 go install golang.org/x/tools/cmd/godoc@latest Once installed, the tool can display documentation for the Go standard library - useful when offline - from any terminal window with this command. 1 godoc The command starts a document server on http://localhost:6060. You can specify a different port if 6060 is in use. 1 godoc -http=:9090 For more information on using Godoc run the command with the help flag.
📄 Page
16
Chapter 1 - Introduction to Go 10 1 godoc -h You can also preview how your code comments will appear as documentation using Godoc. For any package withGoModules support, simply navigate to the folder which contains go.mod in a terminal window and run Godoc. The documentation for the package will be created and listed under the “Third Party” section in the documentation server’s index. 1.4.3 Including example code We can include code examples as part of the generated documentation. These appear as text “code” and “output” sections in the documentation. However, if you run Godoc with the -play option, any such examples become interactive. When interactive, not only can you run code snippets on the Go Playground using the additional Play button which appears top right, but all examples included in the documentation become executable - and editable - programs and not just static text. This is a really useful feature when learning about the standard library. Godoc examples are actually a type of test, and they are run and verified like other tests. We cover testing later in the book, but just like other tests, examples must reside in files named with the _test.go suffix. Within those files, examples are differentiated from normal tests as the function names use the Example and not the Test prefix as shown in the following example taken from the standard library stringutil package. Example 4 - An example function 1 package stringutil_test 2 3 import ( 4 "fmt" 5 6 "golang.org/x/example/stringutil" 7 ) 8 9 func ExampleReverse() { 10 fmt.Println(stringutil.Reverse("hello")) 11 // Output: olleh 12 } Examples do not contain assertions normally associated with unit tests which determine pass or fail. Instead, they contain a commented Output line.
📄 Page
17
Chapter 1 - Introduction to Go 11 The Go test tool checks the actual output of an example function against the output which is on this line. If it matches it passes, if not it fails. This is a useful and overlooked feature when you need to make assertions on functionality which outputs to Stdout. You can use an Example to check it, there’s no need to pipe or redirect the output to a file or variable to compare it. The online Go package repository³ hosts documentation in interactive mode, so you can also experiment with example code there. ³https://pkg.go.dev
📄 Page
18
Chapter 2 - The Go command line interface (CLI) When you download Go you get the Go standard library packages and the Go CLI which is a tool for managing Go source code. You’ll use it for much of what you do with Go, with one or two exceptions, for example, Godoc as we’ve seen. Exploring all the functionality of the Go CLI is left as an exercise for the reader, this section aims to show you how to get started with the tool and highlight specific commands you’ll use most often. You can list all the top-level options of the Go tool using this command. 1 go help If you want to get more help for a specific option use the same command followed by the option. For example, to learn more about the version option run the following command. 1 go help version 2.1 Version information Go has a backwards compatibility guarantee which means that code written in Go version 1.0 can still be compiled and run on the latest Go 1.x version. This doesn’t work the other way, so code written in Go 1.19 may not compile on earlier versions of Go, so you’ll sometimes need to check the version you’re using. To get the current installed Go version run this. 1 go version The output will be similar to below, showing the version, OS, and architecture. 1 go version go1.19 darwin/amd64 2.2 Environment information You can inspect the configuration for your installed Go environment using this command.
📄 Page
19
Chapter 2 - The Go command line interface (CLI) 13 1 go env This outputs all the configuration variables for your installation and can be useful if you are having issues with the Go tool. The variables worth highlighting here are: • GOPATH - the location of your Go src code including the standard library • GOMODCACHE - the location of modules which have been downloaded and cached • GOPROXY - the proxy from which new packages are downloaded For information on other environment variables consult this page⁴. 2.3 Module and workspace management In a later chapter, we’ll cover dependency management in Go and discuss the roles of modules and workspaces. For now, you can familiarise yourself with the module and workspace options via the help subcommand. 1 go mod help 2 go work help 2.4 Format your code If you’re using an IDE like Visual Studio Code with the Go plugin installed, or Goland, then it’s likely your code is formatted automatically upon saving. If you don’t have this facility the fmt subcommand will format your Go source files according to Go standards. Running the tool against a Go source file is straightforward. 1 go fmt main.go 2.5 Testing We’ll get to testing later in the book, for now, it’s enough to know that testing is initiated from the Go tool also. For example to run all the tests in your project use this command from within the project folder. ⁴https://pkg.go.dev/cmd/go#hdr-Environment_variables
📄 Page
20
Chapter 2 - The Go command line interface (CLI) 14 1 go test ./... 2.6 Cleanup Clean removes object files from package source directories. It’s useful if you build an executable and it is placed in the project workspace along with your source. It can be removed, so that it is not committed to version control, with the following command. 1 go clean 2.7 Downloading packages We can use the get command to download package dependencies and install them. We cover this in a later chapter but here’s an example which will add a dependency for a package, or if it is already available, it will upgrade the package to the latest version. 1 go get example.com/pkg 2.8 Running a program Assume you’ve written a program and all the code is saved in file main.go. To run the code navigate to the folder which contains main.go and execute this command. 1 go run main.go If package mainwas made up of multiple Go source files, as is often done to help organise the source code, we could pass all the files to the run command like this. 1 go run *.go The wildcard filename may not work on Windows systems, and you may even run into problems on Mac/Linux when external files for configuration or data are used by your program, in that the paths are not resolvable. So, it’s recommended to build the program and run the resulting executable if you encounter any problems. 2.9 Building your program To build an executable for your current operating system, simply use this command.