brief contents....8
contents....9
preface....16
acknowledgments....18
about this book....19
Who should read this book....20
How this book is organized: A road map....20
About the code....22
liveBook discussion forum....22
Other online resources....23
about the author....24
about the cover illustration....25
Chapter 1 Getting started....27
1.1 Why should you read this book?....27
1.1.1 Learning by example....28
1.1.2 Crafting idiomatic code....28
1.1.3 Crafting testable code....29
1.2 Why Go?....30
1.3 Hello, gophers!....31
1.3.1 Statically and strongly typed language....32
1.3.2 Compilation and static binary....33
1.3.3 Go runtime....34
1.4 Concurrency....34
1.4.1 Goroutines....35
1.4.2 Go scheduler....36
1.4.3 Channels....37
1.5 Type system....38
1.5.1 Composition instead of inheritance....38
1.5.2 Implicit interfaces....39
1.5.3 Testing with implicit interfaces....40
1.6 Standard library....42
1.7 Tooling....43
1.8 Outro....44
1.9 Source code and Go module....44
Chapter 2 Idioms and testing....46
2.1 Groundwork....47
2.1.1 Overview....47
2.1.2 Implementation....48
2.2 Idioms....50
2.2.1 Names....50
2.2.2 Errors....51
2.2.3 Fields....51
2.2.4 Standard interfaces....52
2.3 Testing....53
2.3.1 Writing tests....54
2.3.2 Running tests....55
2.3.3 Writing a failing test....56
2.3.4 Writing descriptive test failure messages....57
2.3.5 Fixing the code....59
2.4 Table-driven tests....61
2.4.1 Creating a table of test cases....62
2.4.2 Writing a table-driven test....63
2.4.3 Running a specific test....64
2.4.4 Identifying problems with table-driven tests....64
2.5 Subtests....66
2.5.1 Understanding subtests....66
2.5.2 Writing a table-driven test with subtests....67
2.5.3 Understanding the role of specific T pointers....68
2.5.4 Running subtests....69
2.5.5 Fixing the code....69
2.6 Example tests....71
2.6.1 Writing an example test....72
2.6.2 Running example tests....73
2.7 Other testing tools....74
Chapter 3 Test coverage and optimization....75
3.1 Test coverage....75
3.1.1 Measuring test coverage....76
3.1.2 Perfecting test coverage....77
3.1.3 100% test coverage ! bug-free code....78
3.2 Benchmarking and optimization....83
3.2.1 Writing and running benchmarks....83
3.2.2 Using sub-benchmarks....86
3.2.3 Profiling: Chasing out memory allocations....87
3.2.4 Optimizing code....88
3.2.5 Comparing benchmarks....90
3.3 Compiler optimizations....93
3.3.1 Inlining and dead-code elimination....93
3.3.2 The sink variable....94
3.3.3 A bright new future....95
3.4 Parallel testing....96
3.4.1 Running tests in parallel....96
3.4.2 Running subtests in parallel....97
3.4.3 Detecting data races....98
3.5 Exercises....100
Chapter 4 Command-line interfaces....101
4.1 Groundwork....102
4.1.1 Implementing the first version....104
4.1.2 Running the first version....105
4.2 Flag parsing....106
4.2.1 Overview....107
4.2.2 Higher-order value parsers....107
4.2.3 Implementing a flag parser....109
4.2.4 Integration and setting sensible defaults....112
4.3 The flag package....114
4.3.1 Integration....114
4.3.2 Demonstration....116
4.4 Value parsers....119
4.4.1 Value interface....120
4.4.2 Satisfying the Value interface....121
4.4.3 Using Var....123
4.5 Positional arguments....125
4.5.1 Flags vs. positional arguments....125
4.5.2 Customizing usage messages....126
4.5.3 Setting a positional argument....127
4.6 Validation....129
4.6.1 Writing a custom validator....129
4.6.2 Validating flags with a custom validator....130
4.7 Exercises....131
Chapter 5 Dependency injection....133
5.1 Challenges to testability....134
5.2 Testable programs....135
5.2.1 Overview....135
5.2.2 A place to store dependencies....136
5.2.3 io.Writers role....136
5.3 Decoupling....138
5.3.1 Decoupling from the environment....138
5.3.2 Decoupling the parsers output....140
5.3.3 Preparing for the HIT client....142
5.3.4 Demonstration....143
5.4 CLI tests....144
5.4.1 Observing with a strings.Builder....144
5.4.2 Streamlining tests....146
5.4.3 Adding a helper....148
5.4.4 Writing CLI tests....151
5.5 Unit testing....152
5.5.1 A helper type....152
5.5.2 Unit-testing the parser....153
Chapter 6 Synchronous APIs ....157
6.1 Overview....158
6.1.1 Package hit....158
6.1.2 Package API....160
6.1.3 Directory structure....161
6.2 Foundations....161
6.2.1 Result....161
6.2.2 Send....162
6.3 Iterators....163
6.3.1 Push iterators....163
6.3.2 Producing values....166
6.3.3 Consuming values....168
6.3.4 Testing....171
6.4 Options....173
6.4.1 Providing options....173
6.4.2 Accepting options....174
6.5 Integration....175
6.5.1 Printing a summary....176
6.5.2 Integration....176
6.5.3 Demonstration....178
6.6 Concurrent pipeline pattern....178
6.6.1 Benefits of concurrent pipelines....178
6.6.2 Designing a concurrent pipeline....179
6.7 Producer stage....180
6.7.1 Implementation....181
6.7.2 Integration....182
6.8 Throttler stage....182
6.8.1 Implementation....183
6.8.2 Integration....184
6.9 Dispatcher stage....185
6.9.1 Implementation....186
6.9.2 Integration....188
6.9.3 Demonstration....189
6.9.4 Outro....191
6.10 Exercises....191
Chapter 7 Responsive and efficient programs....193
7.1 Revisiting the concurrent pipeline....194
7.2 Cancellation propagation....194
7.2.1 What is Context?....195
7.2.2 Context is like a tree....196
7.2.3 Context in practice....198
7.2.4 Deriving a new Context....199
7.2.5 Is CtrlC the end?....200
7.3 HTTP and efficient IO operations....202
7.3.1 Round-tripping....202
7.3.2 Interface composition....203
7.3.3 ReadAll: Eat it all....205
7.3.4 Copy: Eat small, be small....206
7.3.5 Putting it all together....207
7.3.6 Demonstration....209
7.4 Optimization....209
7.4.1 Client and its RoundTripper....210
7.4.2 Tweaking the connection pool....211
7.4.3 Demonstration....212
7.5 Testing....213
7.5.1 Satisfying RoundTripper....213
7.5.2 Testing with a RoundTripper....215
7.6 HTTP testing....216
7.6.1 Package httptest....217
7.6.2 Testing the client....218
7.7 Exercises....219
Chapter 8 Structuring ....221
8.1 Organizing and structuring packages....222
8.1.1 Avoiding import cycles....224
8.1.2 Structuring packages in practice....225
8.2 Core....228
8.2.1 Errors....228
8.2.2 Core....230
8.2.3 Service....233
8.2.4 Mutex....236
8.3 HTTP....239
8.3.1 Health check....240
8.3.2 Serving HTTP....241
8.3.3 HTTP server....242
8.4 HTTP handlers....244
8.4.1 Handler closures....244
8.4.2 Redirecting....246
8.4.3 HTTP status codes....248
8.5 Routing....249
8.5.1 ServeMux....249
8.5.2 Routes....250
8.5.3 Demonstration....251
8.6 Timeouts....251
8.7 Testing....254
8.7.1 Response recording....254
8.7.2 Testing a handler....254
8.7.3 Test helpers....255
8.8 Simplicity....257
8.8.1 Up-front abstractions and indirections....257
8.8.2 Inherently testable types....258
8.9 Exercises....259
Chapter 9 Composition patterns....261
9.1 Middleware pattern....262
9.1.1 What is HTTP middleware?....262
9.1.2 Example....263
9.1.3 Practice....264
9.1.4 Learning more about the slog package and the any interface....265
9.1.5 Integration....267
9.2 Logging responses....268
9.2.1 Measuring durations....269
9.2.2 Response recording....270
9.2.3 Integration....271
9.3 Interceptor pattern....272
9.3.1 Field embedding....273
9.3.2 Capturing and saving....274
9.3.3 Integration....275
9.3.4 Demonstration....276
9.4 Optional interface pattern....277
9.4.1 Type asserting for optional functionality....277
9.4.2 Unwrapping all the way down....278
9.4.3 Unwrap....279
9.5 Context value propagation pattern....280
9.5.1 Generating, storing, and retrieving....280
9.5.2 Middleware....282
9.5.3 Wrapping slog handlers....283
9.5.4 Implementing a slog.Handler....284
9.5.5 Implementing WithAttrs and WithGroup....285
9.5.6 Integration....286
9.6 Handler-chaining pattern....287
9.6.1 Chainable handlers....288
9.6.2 Response handlers....289
9.6.3 Responder....292
9.6.4 Integration....293
9.7 Encoding and decoding....294
9.7.1 Encoding JSON....294
9.7.2 Decoding JSON....295
9.7.3 Speaking JSON....296
9.8 Wrapping and unwrapping....298
9.8.1 Safeguarding against denial-of-service attacks....298
9.8.2 Unwrapping the original....300
9.9 Outro....301
9.10 Exercises....301
Chapter 10 Polymorphic storage....303
10.1 Interacting with SQL databases....304
10.1.1 Registering a driver....306
10.1.2 Opening a connection pool....309
10.1.3 File embedding....311
10.2 Database-backed service....313
10.2.1 Insertion....314
10.2.2 Test database....316
10.2.3 Integration testing....317
10.2.4 errors.As....318
10.2.5 Retrieval....320
10.3 Valuer and Scanner....323
10.3.1 Supporting custom database types....323
10.3.2 Satisfying Valuer and Scanner....324
10.3.3 Encoding and decoding....325
10.4 Implicit interfaces....326
10.4.1 Consumers-first approach....326
10.4.2 Providing an interface....328
10.4.3 Activating the new implementation....330
10.5 Exercises....331
Appendix A Modules and packages....333
A.1 Packages....333
A.1.1 Example....334
A.2 Package main....335
A.3 Modules....336
A.4 Building and running....337
A.5 Exercises....338
Appendix B Variables and pointers....339
B.1 Variables....339
B.2 Pointers....341
B.2.1 What is a pointer?....341
B.2.2 Nil pointers and type safety....342
B.2.3 Address operators....343
B.2.4 Pass-by-value mechanics....344
B.2.5 Stack and heap memory....346
B.3 Exercises....347
Appendix C Arrays, slices, and maps....348
C.1 Arrays....348
C.1.1 Array operations....349
C.1.2 Passing arrays around....349
C.1.3 Passing a pointer....351
C.1.4 Exercises....352
C.2 Slices....352
C.2.1 Usage....352
C.2.2 Underlying arrays....353
C.2.3 Passing slices around....354
C.2.4 Slice expressions and capacity....355
C.2.5 Appending....358
C.2.6 Making slices....360
C.2.7 Strings and byte slices....362
C.2.8 Aliasing effects....362
C.2.9 Copying slices....363
C.2.10 Exercises....364
C.3 Maps....365
C.4 Exercises....367
Appendix D Object-oriented programming....368
D.1 Structs....369
D.1.1 Declaring a new type....369
D.1.2 Creating new values....369
D.1.3 Anonymous types....370
D.1.4 Named types....371
D.2 Methods and receivers....372
D.2.1 Receiver types....372
D.2.2 Value receivers....373
D.2.3 Pointer receivers....375
D.2.4 Avoid mixing receiver types....377
D.2.5 Which receiver type to choose?....378
D.2.6 Exercises....378
D.3 Implicit interfaces....378
D.3.1 Starting with the concrete types....379
D.3.2 Discovering an interface....380
D.3.3 Wiring up....381
D.3.4 Harnessing the power of interfaces....382
D.3.5 Interface values and method sets....383
D.3.6 Exercises....385
D.4 Generics....385
Appendix E Concurrent programming....388
E.1 Goroutines....389
E.1.1 Running sequentially....389
E.1.2 Running concurrently....390
E.2 Using WaitGroup....391
E.2.1 Using syncx.SafeGroup....392
E.2.2 Exercises....394
E.3 Unbuffered channels....395
E.3.1 Usage....395
E.3.2 Synchronization....396
E.3.3 Pattern: Sending and receiving....396
E.4 Closing channels....397
E.4.1 Pattern: for-range....398
E.4.2 Pattern: Coordinating with a closing signal....399
E.5 Using the select statement....400
E.5.1 Waiting for multiple channels....401
E.5.2 Pattern: Nonblocking operations....402
E.6 Buffered channels....403
E.6.1 Pattern: Timing out....404
E.6.2 Directional channels....405
E.6.3 Pattern: Limiting concurrency....406
E.7 Exercises....408
Appendix F Self-referential options....409
F.1 Struct options....409
F.1.1 Zero-value ambiguity....410
F.1.2 Zero-value options....410
F.2 Option functions....410
F.2.1 SendNWith....410
F.2.2 Options as functions....411
F.2.3 Applying options....412
F.2.4 Outro....413
Appendix G Cross-compiling ....415
index....417
Go beyond Go syntax into the language’s unique perspective on program design.
Through engaging hands-on examples, Go by Example will teach you to think differently about programming in Go. You’ll get to grips with the “Go mindset”, writing code that’s simple, straightforward, and easy to understand for your fellow Go developers. You’ll discover how Go’s tooling helps you write code that’s robust and testable, and see just how productive you can be with Go's rich set of built-in packages.
Go by Example explores what makes Go so dramatically different from other languages. Through hands-on and realistic project examples—like command-line tools, web services, and scalable concurrent programs—it helps experienced developers unlearn habits and quickly become productive in crafting truly Go-like, high-quality code.
You can’t appreciate the simplicity, explicitness, and pragmatism of Go until you see it with your own eyes! Even a quick glance at an elegant interface or a bit of clean error handling code reveals why Go was the language of choice for Kubernetes, Docker, and Terraform.
Go by Example unpacks real Go programs to highlight the language features and idiomatic coding practices used by the pros. In it, you’ll dissect and explore examples of command-line tools, concurrent programs, web services, and more as you learn to write Go code that’s simple, efficient, and testable.
For experienced programmers.