Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
1. Setting Up Your Go Environment. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Installing the Go Tools 1
The Go Workspace 2
The go Command 3
go run and go build 3
Getting Third-Party Go Tools 5
Formatting Your Code 6
Linting and Vetting 8
Choose Your Tools 9
Visual Studio Code 9
GoLand 10
The Go Playground 11
Makefiles 13
Staying Up to Date 14
Wrapping Up 16
2. Primitive Types and Declarations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Built-in Types 17
The Zero Value 17
Literals 18
Booleans 19
Numeric Types 20
A Taste of Strings and Runes 26
Explicit Type Conversion 26
var Versus := 27
Using const 29
Typed and Untyped Constants 31
Unused Variables 32
Naming Variables and Constants 33
Wrapping Up 34
3. Composite Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Arrays—Too Rigid to Use Directly 35
Slices 37
len 38
append 39
Capacity 39
make 41
Declaring Your Slice 42
Slicing Slices 43
Converting Arrays to Slices 46
copy 46
Strings and Runes and Bytes 48
Maps 51
Reading and Writing a Map 53
The comma ok Idiom 54
Deleting from Maps 54
Using Maps as Sets 55
Structs 56
Anonymous Structs 58
Comparing and Converting Structs 59
Wrapping Up 60
4. Blocks, Shadows, and Control Structures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Blocks 61
Shadowing Variables 62
Detecting Shadowed Variables 64
if 65
for, Four Ways 67
The Complete for Statement 67
The Condition-Only for Statement 68
The Infinite for Statement 68
break and continue 69
The for-range Statement 71
Labeling Your for Statements 76
Choosing the Right for Statement 77
switch 78
Blank Switches 81
Choosing Between if and switch 83
goto—Yes, goto 83
Wrapping Up 86
5. Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Declaring and Calling Functions 87
Simulating Named and Optional Parameters 88
Variadic Input Parameters and Slices 89
Multiple Return Values 90
Multiple Return Values Are Multiple Values 91
Ignoring Returned Values 91
Named Return Values 92
Blank Returns—Never Use These! 93
Functions Are Values 94
Function Type Declarations 96
Anonymous Functions 96
Closures 97
Passing Functions as Parameters 98
Returning Functions from Functions 99
defer 100
Go Is Call By Value 104
Wrapping Up 106
6. Pointers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
A Quick Pointer Primer 107
Don’t Fear the Pointers 111
Pointers Indicate Mutable Parameters 113
Pointers Are a Last Resort 117
Pointer Passing Performance 118
The Zero Value Versus No Value 118
The Difference Between Maps and Slices 119
Slices as Buffers 122
Reducing the Garbage Collector’s Workload 123
Wrapping Up 127
7. Types, Methods, and Interfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Types in Go 129
Methods 130
Pointer Receivers and Value Receivers 131
Code Your Methods for nil Instances 133
Methods Are Functions Too 134
Functions Versus Methods 135
Type Declarations Aren’t Inheritance 135
Types Are Executable Documentation 136
iota Is for Enumerations—Sometimes 137
Use Embedding for Composition 139
Embedding Is Not Inheritance 140
A Quick Lesson on Interfaces 141
Interfaces Are Type-Safe Duck Typing 142
Embedding and Interfaces 146
Accept Interfaces, Return Structs 146
Interfaces and nil 147
The Empty Interface Says Nothing 148
Type Assertions and Type Switches 150
Use Type Assertions and Type Switches Sparingly 152
Function Types Are a Bridge to Interfaces 154
Implicit Interfaces Make Dependency Injection Easier 155
Wire 159
Go Isn’t Particularly Object-Oriented (and That’s Great) 159
Wrapping Up 160
8. Errors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
How to Handle Errors: The Basics 161
Use Strings for Simple Errors 163
Sentinel Errors 163
Errors Are Values 165
Wrapping Errors 168
Is and As 170
Wrapping Errors with defer 173
panic and recover 174
Getting a Stack Trace from an Error 176
Wrapping Up 176
9. Modules, Packages, and Imports. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Repositories, Modules, and Packages 177
go.mod 178
Building Packages 178
Imports and Exports 178
Creating and Accessing a Package 179
Naming Packages 181
How to Organize Your Module 182
Overriding a Package’s Name 183
Package Comments and godoc 184
The internal Package 185
The init Function: Avoid if Possible 186
Circular Dependencies 187
Gracefully Renaming and Reorganizing Your API 188
Working with Modules 190
Importing Third-Party Code 190
Working with Versions 192
Minimum Version Selection 194
Updating to Compatible Versions 195
Updating to Incompatible Versions 196
Vendoring 197
pkg.go.dev 198
Additional Information 198
Publishing Your Module 199
Versioning Your Module 199
Module Proxy Servers 200
Specifying a Proxy Server 201
Private Repositories 201
Wrapping Up 202
10. Concurrency in Go. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
When to Use Concurrency 203
Goroutines 205
Channels 206
Reading, Writing, and Buffering 206
for-range and Channels 208
Closing a Channel 208
How Channels Behave 209
select 209
Concurrency Practices and Patterns 212
Keep Your APIs Concurrency-Free 212
Goroutines, for Loops, and Varying Variables 213
Always Clean Up Your Goroutines 214
The Done Channel Pattern 215
Using a Cancel Function to Terminate a Goroutine 216
When to Use Buffered and Unbuffered Channels 216
Backpressure 217
Turning Off a case in a select 219
How to Time Out Code 219
Using WaitGroups 220
Running Code Exactly Once 222
Putting Our Concurrent Tools Together 223
When to Use Mutexes Instead of Channels 227
Atomics—You Probably Don’t Need These 230
Where to Learn More About Concurrency 230
Wrapping Up 231
11. The Standard Library. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
io and Friends 233
time 238
Monotonic Time 240
Timers and Timeouts 241
encoding/json 241
Use Struct Tags to Add Metadata 241
Unmarshaling and Marshaling 243
JSON, Readers, and Writers 243
Encoding and Decoding JSON Streams 245
Custom JSON Parsing 246
net/http 247
The Client 247
The Server 249
Wrapping Up 253
12. The Context. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
What Is the Context? 255
Cancellation 258
Timers 261
Handling Context Cancellation in Your Own Code 263
Values 265
Wrapping Up 270
13. Writing Tests. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
The Basics of Testing 271
Reporting Test Failures 273
Setting Up and Tearing Down 273
Storing Sample Test Data 275
Caching Test Results 275
Testing Your Public API 276
Use go-cmp to Compare Test Results 277
Table Tests 278
Checking Your Code Coverage 280
Benchmarks 283
Stubs in Go 286
httptest 291
Integration Tests and Build Tags 294
Finding Concurrency Problems with the Race Checker 295
Wrapping Up 297
14. Here There Be Dragons: Reflect, Unsafe, and Cgo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Reflection Lets Us Work with Types at Runtime 300
Types, Kinds, and Values 301
Making New Values 305
Use Reflection to Check If an Interface’s Value Is nil 306
Use Reflection to Write a Data Marshaler 307
Build Functions with Reflection to Automate Repetitive Tasks 312
You Can Build Structs with Reflection, but Don’t 313
Reflection Can’t Make Methods 314
Only Use Reflection If It’s Worthwhile 314
unsafe Is Unsafe 315
Use unsafe to Convert External Binary Data 316
unsafe Strings and Slices 319
unsafe Tools 320
Cgo Is for Integration, Not Performance 321
Wrapping Up 324
15. A Look at the Future: Generics in Go. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
Generics Reduce Repetitive Code and Increase Type Safety 325
Introducing Generics in Go 328
Use Type Lists to Specify Operators 332
Generic Functions Abstract Algorithms 333
Type Lists Limit Constants and Implementations 334
Things That Are Left Out 337
Idiomatic Go and Generics 339
Further Futures Unlocked 339
Wrapping Up 340
Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Go is rapidly becoming the preferred language for building web services. While there are plenty of tutorials available that teach Go's syntax to developers with experience in other programming languages, tutorials aren't enough. They don't teach Go's idioms, so developers end up recreating patterns that don't make sense in a Go context. This practical guide provides the essential background you need to write clear and idiomatic Go.
No matter your level of experience, you'll learn how to think like a Go developer. Author Jon Bodner introduces the design patterns experienced Go developers have adopted and explores the rationale for using them. You'll also get a preview of Go's upcoming generics support and how it fits into the language.