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/PROJECTgo get github.com/OWNER/REPOgo get github.com/OWNER/REPO@none(uninstall)go run cmd/server/main.gogo build -o server cmd/server/main.goenv GOOS=linux GOARCH=amd64 go build ...go test ./...go test -test.run FUNCdlv debug PKGdlv test PKG -- -test.run FUNC
Be careful
- Reading from a closed channel is not an error. Always do
v, ok := <-ch! breakin a select statement breaks out of theselectstatement 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 ofxis 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
utf8package to work with UTF-8 strings.
Posts
- "HTTP servers in Go" (Apr 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)