Go β Programming Language Guide
Last reviewed: 2026-09-17
Go (Golang) is a statically typed, compiled programming language designed at Google for building efficient, reliable software at scale. It is known for a small language surface, first-class concurrency, fast compilation, and a standard library rich enough to build network services with no third-party dependencies.
Overview
Go emphasises:
- Simplicity β a small language specification, few keywords, one canonical formatting style
- Concurrency β goroutines and channels (CSP model)
- Fast compilation β compiles to a single static binary
- Built-in tooling β
go fmt,go test,go mod,go vet - Standard library β HTTP server, JSON, crypto, templates, testing
Topics Covered
- Packages, modules and import paths
- Variables, structs, interfaces and type composition
- Errors as values,
defer,panic/recover - Goroutines, channels,
syncandcontext - HTTP clients and servers with
net/http - Reading OS-level information with
gopsutil - Message queues and Kafka with
kafka-go - Testing, benchmarking and the race detector
- Cross-compilation and static binaries
Toolchain Commands
go mod init example.com/diskutils # start a module (creates go.mod)
go get github.com/shirou/gopsutil/v3 # add a dependency
go mod tidy # drop unused, fetch missing deps
go build ./... # compile every package
go run main.go # compile and run
go test ./... # run tests
go test -race ./... # run tests with the race detector
go test -bench=. -benchmem ./... # run benchmarks
go vet ./... # static checks
gofmt -l -w . # format (or: go fmt ./...)
go install example.com/tool@latest # install a binary into $(go env GOPATH)/bin
go env GOPATH GOMODCACHE GOOS GOARCH # inspect the toolchain environment
# Cross-compile a static Linux binary from any host
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app ./cmd/app
Errors, defer and Multiple Returns
Go has no exceptions: functions return (value, error) and the caller decides what to do.
package main
import (
"fmt"
"os"
)
func readConfig(path string) ([]byte, error) {
f, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("open config: %w", err)
}
defer f.Close() // runs when readConfig returns
buf := make([]byte, 4096)
n, err := f.Read(buf)
if err != nil {
return nil, err
}
return buf[:n], nil
}
// Call site: unwrap and report, or return the error upward.
if _, err := readConfig("config.yaml"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
%wwraps the underlying error so callers can unwrap it witherrors.Is/errors.As.deferruns LIFO at function exit β use it to close files, unlock mutexes and cancel contexts.- Reserve
panic/recoverfor programmer errors, not for ordinary control flow.
Goroutines and Channels
package main
import (
"fmt"
"sync"
)
func worker(jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for j := range jobs {
results <- j * j
}
}
func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go worker(jobs, results, &wg)
}
for i := 1; i <= 9; i++ {
jobs <- i
}
close(jobs)
wg.Wait()
close(results)
for r := range results {
fmt.Println(r)
}
}
go f()starts a goroutine; the runtime multiplexes goroutines onto OS threads.- Channels are typed and optionally buffered (
make(chan int, 100)); they carry data and synchronisation. sync.WaitGroupwaits for a set of goroutines;context.Contextpropagates cancellation and deadlines.- The race detector (
go test -race) is the cheapest way to find concurrent access bugs.
Reading System Information with gopsutil
gopsutil exposes OS-level metrics (disk, CPU, memory, processes, network) from pure Go. This example lists every mounted partition:
package main
import (
"fmt"
"github.com/shirou/gopsutil/v3/disk"
)
func main() {
partitions, err := disk.Partitions(true)
if err != nil {
fmt.Println("error:", err)
return
}
if len(partitions) == 0 {
fmt.Println("No disks found")
return
}
for _, p := range partitions {
fmt.Printf("device=%s mountpoint=%s fstype=%s\n", p.Device, p.Mountpoint, p.Fstype)
}
}
Patterns worth reusing:
- Third-party packages are pulled in with
go getand pinned ingo.mod/go.sum. - Idiomatic Go returns errors instead of panicking β check
erron every call. - Related helpers exist for usage statistics (
disk.Usage("/")), CPU (cpu.Percent), memory (mem.VirtualMemory) and processes (process.Processes). - Combined with
net/http, the same data can be exposed as a small JSON endpoint for monitoring.
Kafka Messaging with kafka-go
segmentio/kafka-go is a pure-Go Kafka client β no cgo, no librdkafka:
// Producing
w := &kafka.Writer{
Addr: kafka.TCP("localhost:9092"),
Topic: "orders",
Balancer: &kafka.LeastBytes{},
BatchTimeout: 10 * time.Millisecond,
RequiredAcks: kafka.RequireAll,
}
defer w.Close()
w.WriteMessages(ctx, kafka.Message{Key: []byte("order-1"), Value: []byte(`{"id":"order-1"}`)})
// Consuming with a consumer group
r := kafka.NewReader(kafka.ReaderConfig{Brokers: brokers, Topic: "orders", GroupID: "order-workers"})
defer r.Close()
for {
m, err := r.ReadMessage(ctx)
if err != nil {
break // context cancelled, partition closed, broker unavailable
}
fmt.Printf("key=%s value=%s\n", m.Key, m.Value)
}
Notes:
- Message keys determine partition assignment β the same key always lands on the same partition, preserving per-entity ordering.
- Protocol Buffers are a common payload format for strongly typed messages (
protoc --go_out=. order.proto). - Writers batch by size and time (
BatchSize/BatchTimeout); consumer groups give at-least-once delivery with automatic rebalancing across instances.
Key Go Concepts
| Concept | Description |
|---|---|
| Packages & modules | package main, go mod init, import paths |
| Multiple returns | func div(a, b int) (int, error) |
| Goroutines | go funcName() β lightweight threads |
| Channels | ch := make(chan int) β typed communication pipes |
| Interfaces | Implicit implementation β "duck typing" at compile time |
| Structs | Type composition over inheritance |
| Error handling | Explicit error returns, no exceptions |
defer |
Scheduled cleanup (close file, unlock mutex) |
context |
Cancellation, deadlines, request-scoped values |
Resources
- Go Documentation
- Go by Example
- Effective Go
- gopsutil β Go process/system utilities
- kafka-go β Kafka client for Go
- Fyne β Cross-Platform GUI Toolkit for Go β the Fyne article in this KB
To-do
Status: incomplete. Still to write:
- Write the 'HTTP clients and servers with net/http' section promised in Topics Covered β no net/http example exists in the article (it is only mentioned in passing under gopsutil).
- Expand 'Variables, structs, interfaces and type composition' beyond the one-line table rows β interfaces are promised in Topics Covered but only named.
- Show
sync/contextin use: cancellation and deadlines are promised alongside goroutines but appear only as prose bullets, with no context example.