Preface xvii
Chapter 1: A Quick Introduction to Go 1
Introducing Go .................................................................................................................... 2
The history of Go • 2
The advantages of Go • 4
When to use Go ................................................................................................................... 5
My personal Go journey • 6
The go doc and godoc utilities • 7
Hello World! ........................................................................................................................ 8
Introducing functions • 9
Introducing packages • 10
Running Go code ............................................................................................................... 10
Compiling Go code • 10
Using Go like a scripting language • 11
Important formatting and coding rules • 11
What you should know about Go ....................................................................................... 13
Defining and using variables • 13
Constants • 14
Global variables • 14
Printing variables • 14
Controlling program flow • 16
Iterating with for loops and range • 19
Getting user input • 21
Reading from standard input • 22
Working with command line arguments • 22
Using error variables to differentiate between input types • 26
Understanding the Go concurrency model • 29
Developing the which(1) utility in Go ................................................................................ 31
Logging information ......................................................................................................... 33
log.Fatal() and log.Panic() • 35
Writing to a custom log file • 37
Printing line numbers in log entries • 39
Writing to multiple log files • 40
Developing a statistics application ................................................................................... 41
Summary .......................................................................................................................... 44
Exercises ........................................................................................................................... 44
Additional resources ......................................................................................................... 44
Chapter 2: Basic Go Data Types 47
The error data type ........................................................................................................... 48
Numeric data types ........................................................................................................... 52
Avoiding overflows • 54
Non-numeric data types ................................................................................................... 55
Strings, characters, and runes • 56
Converting int to string • 58
The unicode package • 59
The strings package • 60
Times and dates • 63
Working with different time zones • 65
Constants .......................................................................................................................... 66
The constant generator iota • 66
Typed and untyped constants • 69
Grouping similar data ....................................................................................................... 70
Arrays • 70
Slices • 70
About slice length and capacity • 73
Selecting a part of a slice • 76
Byte slices • 78
Deleting an element from a slice • 80
How slices are connected to arrays • 83
Catching out of bounds errors • 85
The copy() function • 86
Sorting slices • 88
Pointers ............................................................................................................................. 90
Converting a slice to an array or an array pointer • 94
Data types and the unsafe package ................................................................................... 95
Generating random numbers ............................................................................................ 97
Generating random strings • 99
Generating secure random numbers • 100
Updating the statistics application .................................................................................. 101
Summary ........................................................................................................................ 102
Exercises ......................................................................................................................... 103
Additional resources ....................................................................................................... 103
Chapter 3: Composite Data Types 105
Maps ............................................................................................................................... 106
How to tell whether a key exists on a map • 107
Storing to a nil map • 107
Iterating over maps • 109
Structures ........................................................................................................................ 110
The type keyword • 110
Defining new structures • 110
Using the new keyword • 112
Slices of structures • 114
Regular expressions and pattern matching ...................................................................... 116
About regexp.Compile and regexp.MustCompile • 116
Go regular expressions • 118
About raw string and interpreted string literals • 119
Matching names and surnames • 119
Matching integers • 120
Improving the statistics application ................................................................................ 121
Working with CSV files • 121
The updated version of the statistics application • 126
Summary ......................................................................................................................... 129
Exercises ......................................................................................................................... 130
Additional resources ....................................................................................................... 130
Chapter 4: Go Generics 133
An introduction to generics .............................................................................................. 134
Hello, generics! • 135
Constraints ...................................................................................................................... 136
Creating constraints • 137
Supporting underlying data types • 139
Supporting slices of any type • 140
Defining new data types with generics ........................................................................... 140
Using generics in Go structures • 142
The cmp package ............................................................................................................. 145
The slices package ............................................................................................................ 145
Shallow and deep copies • 146
The maps package ........................................................................................................... 148
When to use generics ...................................................................................................... 150
Summary ......................................................................................................................... 151
Exercises .......................................................................................................................... 151
Additional resources ........................................................................................................ 152
Chapter 5: Reflection and Interfaces 153
Reflection ......................................................................................................................... 154
Understanding the internal structure of a Go structure • 155
Changing structure values using reflection • 158
The three disadvantages of reflection • 159
Type methods ................................................................................................................. 160
Creating type methods • 160
Value and point receivers • 161
Using type methods • 162
Interfaces ......................................................................................................................... 165
The sort.Interface interface • 168
The empty interface • 170
Type assertions and type switches • 172
The map[string]interface{} map • 177
The error data type • 181
Writing your own interfaces • 184
Using a Go interface • 185
Object-oriented programming in Go ............................................................................... 186
Interfaces versus generics ............................................................................................... 190
Reflection versus generics ................................................................................................ 193
Updating the statistics application .................................................................................. 195
Summary ........................................................................................................................ 198
Exercises ......................................................................................................................... 199
Additional resources ....................................................................................................... 199
Chapter 6: Go Packages and Functions 201
Go packages .................................................................................................................... 202
About go get and go install • 203
Functions ........................................................................................................................ 206
Anonymous functions • 206
Functions that return multiple values • 207
The return values of a function can be named • 208
Functions that accept other functions as parameters • 209
Functions can return other functions • 211
Variadic functions • 212
The defer keyword • 216
Big O complexity .............................................................................................................. 219
Developing your own packages ........................................................................................ 219
The init() function • 220
Order of execution • 221
Using GitHub to store Go packages ................................................................................. 223
A package for working with SQLite ................................................................................. 224
Working with SQLite3 and Go • 225
Storing the Go package • 234
The design of the Go package • 234
The implementation of the Go package • 235
Testing the Go package • 244
Modules .......................................................................................................................... 250
Creating better packages ................................................................................................ 250
Generating documentation ............................................................................................. 252
Workspaces ..................................................................................................................... 257
Versioning utilities .......................................................................................................... 260
Summary ........................................................................................................................ 262
Exercises ......................................................................................................................... 263
Additional resources ....................................................................................................... 263
Chapter 7: Telling a UNIX System What to Do 265
stdin, stdout, and stderr ................................................................................................. 266
UNIX processes ............................................................................................................... 266
File I/O ............................................................................................................................ 267
The io.Reader and io.Writer interfaces • 267
Using and misusing io.Reader and io.Writer • 268
Buffered and unbuffered file I/O • 272
Reading text files ............................................................................................................. 273
Reading a text file line by line • 273
Reading a text file word by word • 275
Reading a text file character by character • 276
Reading from /dev/random • 278
Reading a specific amount of data from a file • 279
Writing to a file ............................................................................................................... 280
Working with JSON ......................................................................................................... 283
Using Marshal() and Unmarshal() • 283
Structures and JSON • 285
Reading and writing JSON data as streams • 287
Pretty printing JSON records • 288
The viper package ........................................................................................................... 290
Using command line flags • 290
Reading JSON configuration files • 293
The cobra package .......................................................................................................... 297
A utility with three commands • 299
Adding command line flags • 299
Creating command aliases • 300
Creating subcommands • 301
Important Go features .................................................................................................... 302
Embedding files • 302
ReadDir and DirEntry • 305
The io/fs package • 307
Updating the statistics application ................................................................................. 309
The slog package • 310
Sending logs to io.Discard • 312
Using cobra • 312
Storing and loading JSON data • 314
Implementing the list command • 315
Implementing the insert command • 316
Summary ......................................................................................................................... 317
Exercises ......................................................................................................................... 318
Additional resources ....................................................................................................... 318
Chapter 8: Go Concurrency 321
Processes, threads, and goroutines ................................................................................. 322
The Go scheduler ............................................................................................................ 323
The GOMAXPROCS environment variable • 325
Concurrency and parallelism • 326
Goroutines ...................................................................................................................... 327
Creating a goroutine • 327
Creating multiple goroutines • 328
Waiting for all goroutines to finish • 329
What if the number of Add() and Done() calls differ? • 331
Creating multiple files with goroutines • 333
Channels ......................................................................................................................... 334
Writing to and reading from a channel • 334
Receiving from a closed channel • 337
Channels as function parameters • 338
Race conditions are bad .................................................................................................. 339
The Go race detector • 340
The select keyword ......................................................................................................... 342
Timing out a goroutine ................................................................................................... 344
Timing out a goroutine inside main() • 344
Timing out a goroutine outside main() • 346
Go channels revisited ...................................................................................................... 347
Buffered channels • 348
nil channels • 350
Worker pools • 351
Signal channels • 355
Specifying the order of execution for your goroutines • 355
Handling UNIX signals .................................................................................................... 358
Handling two signals • 361
Shared memory and shared variables .............................................................................. 361
The sync.Mutex type • 361
What happens if you forget to unlock a mutex? • 363
The sync.RWMutex type • 364
The atomic package • 367
Sharing memory using goroutines • 369
Closured variables and the go statement ........................................................................ 372
The context package ....................................................................................................... 374
About context.WithCancelCause • 378
The semaphore package .................................................................................................. 379
Making the statistics application concurrent ................................................................. 382
Summary ........................................................................................................................ 385
Exercises ......................................................................................................................... 385
Additional resources ....................................................................................................... 386
Chapter 9: Building Web Services 387
The net/http package ...................................................................................................... 387
The http.Response type • 388
The http.Request type • 388
The http.Transport type • 389
Creating a web server ...................................................................................................... 390
Updating the statistics application ................................................................................. 394
Defining the API • 394
Implementing the handlers • 395
Creating a Docker image • 404
Developing web clients ................................................................................................... 406
Using http.NewRequest() to improve the client • 408
Using errGroup • 411
Creating a client for the statistics service ......................................................................... 413
Timing out HTTP connections ........................................................................................ 419
Using SetDeadline() • 419
Setting the timeout period on the client side • 421
Setting the timeout period on the server side • 423
Summary ........................................................................................................................ 424
Exercises ......................................................................................................................... 424
Additional resources ....................................................................................................... 424
Chapter 10: Working with TCP/IP and WebSocket 427
TCP/IP ............................................................................................................................. 428
The nc(1) command line utility • 429
The net package .............................................................................................................. 429
Developing a TCP client .................................................................................................. 430
Developing a TCP client with net.Dial() • 430
Developing a TCP client that uses net.DialTCP() • 432
Developing a TCP server ................................................................................................. 434
Developing a TCP server with net.Listen() • 434
Developing a TCP server that uses net.ListenTCP() • 437
Developing a UDP client ................................................................................................. 439
Developing a UDP server ................................................................................................. 441
Developing concurrent TCP servers ................................................................................ 444
Creating a WebSocket server ........................................................................................... 447
The implementation of the server • 448
Using websocat • 451
Creating a WebSocket client ........................................................................................... 453
Working with RabbitMQ ................................................................................................. 457
Running RabbitMQ • 458
Writing to RabbitMQ • 459
Reading from RabbitMQ • 461
How to remove a module • 463
Summary ........................................................................................................................ 463
Exercises ......................................................................................................................... 464
Additional resources ....................................................................................................... 464
Chapter 11: Working with REST APIs 467
An introduction to REST ................................................................................................. 468
Developing RESTful servers and clients .......................................................................... 470
A RESTful server • 471
A RESTful client • 480
Creating a functional RESTful server .............................................................................. 490
The REST API • 490
Using gorilla/mux • 491
The use of subrouters • 492
The Gin HTTP framework • 493
Gin versus Gorilla • 493
Working with the database • 493
Implementing the RESTful server • 498
Testing the RESTful server • 503
Testing GET handlers • 504
Testing POST handlers • 505
Testing the PUT handler • 506
Testing the DELETE handler • 507
Creating a RESTful client ................................................................................................ 507
Creating the structure of the command line client • 508
Implementing the RESTful client commands • 509
Using the RESTful client • 514
Working with multiple REST API versions • 515
Summary ......................................................................................................................... 516
Exercises .......................................................................................................................... 516
Additional resources ........................................................................................................ 517
Chapter 12: Code Testing and Profiling 519
Optimizing code ............................................................................................................. 520
Rewriting the main() function for better testing ............................................................. 521
Profiling code .................................................................................................................. 522
Profiling a command line application • 523
Profiling an HTTP server • 527
The web interface of the Go profiler • 529
The go tool trace utility • 531
Tracing a web server from a client • 533
Visiting all routes of a web server • 536
Testing Go code ............................................................................................................... 540
Writing tests for ./ch03/intRE.go • 541
Testing UNIX signals • 543
Disabling test caching • 546
The testing.TempDir() function • 546
The Cleanup() function • 546
The testing/quick package • 549
Timing out tests • 551
Testing using testing.T.Fatal() and testing.T.Fatalf() • 552
Table-driven tests • 554
Testing code coverage • 556
Finding unreachable Go code • 559
Testing an HTTP server with a database backend • 562
The govulncheck tool ...................................................................................................... 568
Installing the tool • 568
Cross-compilation .......................................................................................................... 572
Using go:generate • 573
Creating example functions ............................................................................................ 576
Summary ......................................................................................................................... 577
Exercises ......................................................................................................................... 578
Additional resources ....................................................................................................... 578
Chapter 13: Fuzz Testing and Observability 581
Fuzz testing .................................................................................................................... 582
A simple fuzz testing example • 583
An advanced fuzz testing example • 586
Correcting the bug • 592
Observability .................................................................................................................. 598
The runtime/metrics package • 599
Measuring the execution time of a function • 601
The expvar package • 603
Learning about CPU characteristics • 605
Exposing metrics to Prometheus .................................................................................... 607
Exposing metrics • 607
Creating a Docker image for a Go server • 611
Specifying the metrics to expose • 613
Getting the metrics • 616
Putting the metrics in Prometheus • 617
Visualizing Prometheus metrics in Grafana • 622
Summary ........................................................................................................................ 624
Exercises ......................................................................................................................... 624
Additional resources ....................................................................................................... 624
Chapter 14: Efficiency and Performance 627
Benchmarking code ........................................................................................................ 628
A simple benchmark scenario • 629
Benchmarking the number of memory allocations • 632
Initial version • 632
Improving the number of memory allocations • 633
Buffered versus unbuffered file I/O ................................................................................. 637
The benchstat utility • 641
Wrongly defined benchmark functions ........................................................................... 643
Go memory management ................................................................................................ 644
Heap and stack • 644
The main elements of the Go memory model • 648
Memory leaks ................................................................................................................. 648
Slices and memory leaks • 649
Maps and memory leaks • 651
Memory pre-allocation • 652
Working with eBPF ......................................................................................................... 654
What is eBPF? • 654
About observability and eBPF • 655
Creating an eBPF tool in Go • 655
Summary ........................................................................................................................ 659
Exercises ......................................................................................................................... 659
Additional resources ....................................................................................................... 659
Chapter 15: Changes in Recent Go Versions 661
About rand.Seed() ........................................................................................................... 661
What is new in Go 1.21? ................................................................................................... 662
The sync.OnceFunc() function • 662
The clear function • 664
What is new in Go 1.22? ................................................................................................... 665
Changes in slices • 666
Changes in for loops • 667
The math/rand/v2 package • 668
Summary ........................................................................................................................ 670
Exercises ......................................................................................................................... 670
Additional resources ....................................................................................................... 670
Appendix: The Go Garbage Collector 673
Garbage collection .......................................................................................................... 673
The key characteristics of the Go GC ............................................................................... 674
Learning more about the Go GC ...................................................................................... 674
The tri-color algorithm • 677
More about the operation of the Go GC • 680
Maps, slices, and the Go GC ............................................................................................ 681
Using slices • 681
Using maps with pointers • 682
Using maps without pointers • 683
Splitting a map • 683
Comparing the performance of the presented techniques • 684
Additional resources ....................................................................................................... 685
Other Books You May Enjoy 689
Index 693
Mastering Go, now in its fourth edition, remains the go-to resource for real-world Go development. This comprehensive guide delves into advanced Go concepts, including RESTful servers, and Go memory management. This edition brings new chapters on Go Generics and fuzzy Testing, and an enriched exploration of efficiency and performance. As you work your way through the chapters, you will gain confidence and a deep understanding of advanced Go topics, including concurrency and the operation of the Garbage Collector, using Go with Docker, writing powerful command-line utilities, working with JavaScript Object Notation (JSON) data, and interacting with databases.
You will be engaged in real-world exercises, build network servers, and develop robust command-line utilities. With in-depth chapters on RESTful services, the WebSocket protocol, and Go internals, you are going to master Go's nuances, optimization, and observability. You will also elevate your skills in efficiency, performance, and advanced testing.
With the help of Mastering Go, you will become an expert Go programmer by building Go systems and implementing advanced Go techniques in your projects.
Learn Go data types, error handling, constants, pointers, and array and slice manipulations through practical exercises
Create generic functions, define data types, explore constraints, and grasp interfaces and reflections
Grasp advanced concepts like packages, modules, functions, and database interaction
Create concurrent RESTful servers, and build TCP/IP clients and servers
Learn testing, profiling, and efficient coding for high-performance applications
Develop an SQLite package, explore Docker integration, and embrace workspaces
Mastering Go is written primarily for Go programmers who have some experience with the language and want to become expert practitioners. You will need to know the basics of computer programming before you get started with this book, but beyond that, anyone can sink their teeth into it.