Go
A programming language designed at Google and released in 2009. Statically-typed, compiled, and garbage-collected. Known for its pugnacious approach to language design and strong support for concurrency using green threads called goroutines and synchronized queues called channels.
Cheatsheet
Goroutines and channels
// buffer of 100 elements
ch := make(chan int, 100)
x, ok := <-ch // blocks if nothing to read
ch <- x // blocks until read (if unbuffered) or if buffer is full
// non-blocking read
select {
case x, ok := <-ch:
// ...
default:
// ...
}
// non-blocking write
select {
case ch <- x:
// ...
case <-context.Done():
return
default:
// ...
}
// wait for goroutines to finish
var wg sync.WaitGroup
wg.Add(1) // outside the goroutine!
go func() {
defer wg.Done()
...
}
wg.Wait()
Cancel a goroutine
doneChannel := make(chan struct{})
go func() {
time.Sleep(1 * time.Minute)
close(doneChannel)
}()
go func() {
for {
// ...
select {
case <-doneChannel:
return
default:
continue
}
}
}()
Loops
for my_condition { ... }
for i := 0 ; i < n; i++ { ... }
for i, x := range xs { ... }
Type assertions and switches
s, ok := x.(string)
switch t := x.(type) {
case T1:
// `t` is value of type `T1`
case T2:
// `t` is value of type `T2`
default:
// ...
}
Package organization
- Commands go in
cmd/PACKAGE/main.go
; private packages go ininternal/
.
Commands
go mod init github.com/iafisher/PROJECT
go get github.com/OWNER/REPO
go get github.com/OWNER/REPO@none
(uninstall)go run cmd/server/main.go
go build -o server cmd/server/main.go
env GOOS=linux GOARCH=amd64 go build ...
go test ./...
go test -test.run FUNC
dlv debug PKG
dlv test PKG -- -test.run FUNC
Be careful
- Reading from a closed channel is not an error. Always do
v, ok := <-ch
! break
in a select statement breaks out of theselect
statement itself, not any outer loop.- If spawning goroutines in a loop, don't do
for _, x := range xs { go func() { ... x ... }() }
– instead dogo func(x T) { ... }(x)
to ensure the correct value ofx
is captured. - If passing an anonymous function to
defer
, make sure to call it:defer func() { ... }()
- Indexing a string gives you a byte, not a Unicode character. Use the
utf8
package to work with UTF-8 strings.
Posts
- "HTTP servers in Go" (April 2025)
Bibliography
Reference and overview:
Programming practices:
- "One process programming notes (with Go and SQLite)" (David Crawshaw, 2018)
- "Practical Go: Real world advice for writing maintainable Go programs" (Dave Cheney, 2019)
- "Go’s features of last resort" (Martin Tournoij, 2019)
- "On the uses and misuses of panics in Go" (Eli Bendersky, 2018)
Tooling and operations:
- "Building static binaries with Go on Linux" (Eli Bendersky, 2024)
- "Statically compiled Go programs, always, even with cgo, using musl" (Dominik Honnef, 2015)
- "Shrink your Go binaries with this one weird trick" (Filippo Valsorda, 2016)
Concurrency:
- Channel/goroutine behavior by example
- "Go Concurrency Patterns: Context" (Sameer Ajmani @ The Go Blog, 2014)
- "Go Concurrency Patterns: Pipelines and cancellation" (Sameer Ajmani @ The Go Blog, 2014)
- "Understanding Real-World Concurrency Bugs in Go" (Tengfei Tu et al, 2019)
- "Go hits the concurrency nail right on the head" (Eli Bendersky, 2018)
- "Why you can have millions of Goroutines but only thousands of Java Threads" (Russell Cohen, 2018)
- "Data Race Detector"
Language comparisons:
- "Einstein Analytics and Go" (Guillaume Le Stum @ Stack Overflow, 2019) – rewriting a backend from Python to Go
- "Why Go and not Rust?" (Loris Cro, 2019)
Language evolution:
- "Go 2 Draft Designs"
- "Backward Compatibility, Go 1.21, and Go 2" (Russ Cox, 2023)
Internals:
- "Go channels on steroids" (Dmitry Vyukov, 2014)
chan.go
– the actual implementation of channels
- "The Go runtime scheduler's clever way of dealing with system calls" (Chris Siebenmann, 2019)
- "Go's work-stealing scheduler" (rakyll, 2017)
- "The Go scheduler" (Daniel Morsing, 2013)
- "The Go netpoller" (Daniel Morsing, 2013)
-
- "The Go runtime scheduler's clever way of dealing with system calls" (Chris Siebenmann, 2019)
- "Some reasons for Go to not make system calls through the standard C library" (Chris Siebenmann, 2019)
- "Go compiler internals: adding a new statement to Go - Part 1" (Eli Bendersky, 2019)
- "Proposal: Register-based Go calling convention" (Austin Clements, 2020)
- "Getting to Go: The Journey of Go's Garbage Collector" (Rick Hudson, 2018)
Commentary:
- "Go at Google: Language Design in the Service of Software Engineering" (Rob Pike, 2012)
- "Go is Google's language, not ours" (Chris Siebenmann, 2019)
- "Ten Reasons Why I Don't Like Golang" (Lawrence Kesteloot, 2016)
- "I want off Mr. Golang's Wild Ride" (fasterthanlime, 2020)
- "Go Is a Shop-built Jig" (Rob Napier, 2014)
- "The Value in Go's Simplicity" (Ben Congdon, 2019)