Golang
Updated: May 21, 2026Categories: Languages
Printed from:
Go (Golang) Cheatsheet
Language Overview
Go is a statically typed, compiled programming language designed at Google by Robert Griesemer, Rob Pike, and Ken Thompson. It focuses on simplicity, efficiency, and robust concurrent programming.
Key Characteristics:
- Compiled language with fast execution
- Statically typed with garbage collection
- Built-in concurrency support via goroutines and channels
- Strong standard library
- Explicit error handling
- Efficient memory management
- Cross-platform compilation
- Generics support (since Go 1.18)
- Range-over-function iterators (since Go 1.23)
Basic Syntax
Hello World
Go
12345678package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
Program Structure
Go
12345678package main // Package declaration
import "fmt" // Import statements
// Main function - entry point of the program
func main() {
// Program logic
}
Data Types
Primitive Types
Go
123456789101112131415161718192021222324252627282930313233// Integers
var i int // Platform-dependent integer (32 or 64 bit)
var i8 int8 // 8-bit signed integer
var i16 int16 // 16-bit signed integer
var i32 int32 // 32-bit signed integer (alias: rune)
var i64 int64 // 64-bit signed integer
// Unsigned Integers
var u uint // Unsigned platform-dependent integer
var b byte // Alias for uint8
var u16 uint16 // 16-bit unsigned integer
var uptr uintptr // Unsigned integer large enough to hold a pointer
// Floating Point
var f32 float32 // 32-bit floating point
var f64 float64 // 64-bit floating point
// Complex Numbers
var c64 complex64 // Complex with float32 parts
var c128 complex128 // Complex with float64 parts
// Boolean
var boolean bool // true or false (zero value: false)
// String
var text string // Immutable UTF-8 string (zero value: "")
// Character (rune)
var char rune // Unicode code point (alias for int32)
// Empty interface alias (Go 1.18+)
var a any // Equivalent to interface{}
Collection Types
Go
123456789101112131415161718192021// Arrays (Fixed Size)
var arr [5]int = [5]int{1, 2, 3, 4, 5}
// Slices (Dynamic Arrays)
slice := []int{1, 2, 3, 4, 5}
slice = append(slice, 6)
// Maps (Hash Tables/Dictionaries)
m := map[string]int{
"apple": 1,
"banana": 2,
}
m["orange"] = 3
clear(m) // Built-in clear (Go 1.21+)
// Struct
type Person struct {
Name string
Age int
}
Variables and Constants
Go
123456789101112131415161718// Variable Declaration
var name string = "John"
age := 30 // Short declaration (type inferred)
// Multiple Variable Declaration
var x, y int = 10, 20
// Constants
const Pi = 3.14159
const (
StatusOK = 200
NotFound = 404
)
// Built-in helpers (Go 1.21+)
biggest := max(1, 7, 3) // 7
smallest := min(1, 7, 3) // 1
Operators
Arithmetic Operators
Go
12345678a := 10
b := 3
sum := a + b // Addition
diff := a - b // Subtraction
prod := a * b // Multiplication
div := a / b // Division
mod := a % b // Modulus
Comparison Operators
Go
1234567a == b // Equal
a != b // Not Equal
a < b // Less Than
a > b // Greater Than
a <= b // Less Than or Equal
a >= b // Greater Than or Equal
Logical Operators
Go
1234true && false // Logical AND
true || false // Logical OR
!true // Logical NOT
Control Structures
If/Else Statements
Go
12345678910111213if x > 0 {
fmt.Println("Positive")
} else if x < 0 {
fmt.Println("Negative")
} else {
fmt.Println("Zero")
}
// Compact if statement with initialization
if y := someFunction(); y > 10 {
// Use y here
}
Switch Statements
Go
1234567891011121314151617switch day {
case "Mon", "Tue", "Wed", "Thu", "Fri":
fmt.Println("Weekday")
case "Sat", "Sun":
fmt.Println("Weekend")
default:
fmt.Println("Unknown")
}
// Type switch
switch v := value.(type) {
case int:
fmt.Println("int:", v)
case string:
fmt.Println("string:", v)
}
Loops
Go
123456789101112131415161718192021222324252627282930// Traditional for loop
for i := 0; i < 5; i++ {
fmt.Println(i)
}
// While-like loop
for x < 10 {
x++
}
// Infinite loop
for {
// Do something
break // Exit condition
}
// Range-based iteration
numbers := []int{1, 2, 3, 4, 5}
for index, value := range numbers {
fmt.Printf("Index: %d, Value: %d\n", index, value)
}
// Range over an integer (Go 1.22+)
for i := range 5 {
fmt.Println(i) // 0..4
}
// Note: since Go 1.22, each loop iteration creates fresh variables,
// so capturing the loop variable in a goroutine or closure is now safe.
Functions
Go
1234567891011121314151617181920212223242526// Basic Function
func add(a, b int) int {
return a + b
}
// Multiple Return Values
func divideNumbers(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
// Variadic Functions
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
// Function as a Variable
var operation func(int, int) int
operation = add
Generics (Go 1.18+)
Go
1234567891011121314151617181920212223242526// Generic function with type parameter
func Map[T, U any](s []T, f func(T) U) []U {
out := make([]U, len(s))
for i, v := range s {
out[i] = f(v)
}
return out
}
// Type constraints
type Ordered interface {
~int | ~int64 | ~float64 | ~string
}
func Min[T Ordered](a, b T) T {
if a < b {
return a
}
return b
}
// Generic type
type Stack[T any] struct {
items []T
}
Iterators (Go 1.23+)
Go
1234567891011121314151617import "iter"
// Function-style iterator
func Count(n int) iter.Seq[int] {
return func(yield func(int) bool) {
for i := 0; i < n; i++ {
if !yield(i) {
return
}
}
}
}
for v := range Count(5) {
fmt.Println(v)
}
Pointers
Go
123456var x int = 10
var ptr *int = &x // Pointer to x
*ptr = 20 // Dereferencing and modifying value
fmt.Println(x) // Prints 20
Structs and Methods
Go
1234567891011121314151617181920type Rectangle struct {
width, height float64
}
// Value-receiver method
func (r Rectangle) Area() float64 {
return r.width * r.height
}
// Pointer-receiver method (use for mutation or large structs)
func (r *Rectangle) Scale(factor float64) {
r.width *= factor
r.height *= factor
}
// Constructor-like function
func NewRectangle(w, h float64) *Rectangle {
return &Rectangle{width: w, height: h}
}
Interfaces
Go
12345678910111213141516type Shape interface {
Area() float64
}
// Implementing Interface (implicit; no "implements" keyword)
func (r Rectangle) Area() float64 {
return r.width * r.height
}
// `any` is the preferred alias for the empty interface
func PrintAll(values ...any) {
for _, v := range values {
fmt.Println(v)
}
}
Error Handling
Go
1234567891011121314151617181920import "errors"
var ErrDivideByZero = errors.New("division by zero")
func divideNumbers(a, b int) (int, error) {
if b == 0 {
// %w wraps a sentinel error so callers can use errors.Is / errors.As
return 0, fmt.Errorf("divideNumbers: %w", ErrDivideByZero)
}
return a / b, nil
}
result, err := divideNumbers(10, 0)
if err != nil {
if errors.Is(err, ErrDivideByZero) {
fmt.Println("cannot divide by zero")
}
fmt.Println("Error:", err)
}
Concurrency
Goroutines
Go
123456func sayHello() {
fmt.Println("Hello")
}
go sayHello() // Runs concurrently
Channels
Go
1234567891011121314151617181920ch := make(chan int) // Unbuffered channel
bch := make(chan int, 10) // Buffered channel
go func() {
ch <- 42 // Send value to channel
close(ch) // Signal no more sends
}()
value, ok := <-ch // Receive; ok=false when closed and drained
// Select for multiplexing
select {
case v := <-ch:
fmt.Println("got", v)
case bch <- 1:
fmt.Println("sent")
default:
fmt.Println("no comms ready")
}
Synchronization
Go
123456789101112import "sync"
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
// Concurrent work
}()
wg.Wait() // Wait for goroutine to complete
// sync.Once / sync.Mutex / sync.RWMutex available for typical patterns
Context (cancellation, deadlines, values)
Go
123456789101112131415import (
"context"
"time"
)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
select {
case <-time.After(3 * time.Second):
fmt.Println("work done")
case <-ctx.Done():
fmt.Println("cancelled:", ctx.Err())
}
Standard-Library Highlights
Structured Logging — log/slog (Go 1.21+)
Go
12345678import "log/slog"
slog.Info("request handled",
"method", "GET",
"status", 200,
"duration_ms", 42,
)
Slices and Maps Helpers (Go 1.21+)
Go
1234567891011121314import (
"slices"
"maps"
)
s := []int{3, 1, 2}
slices.Sort(s) // [1 2 3]
i, found := slices.BinarySearch(s, 2)
s = slices.Delete(s, 0, 1)
m1 := map[string]int{"a": 1}
m2 := maps.Clone(m1)
keys := slices.Collect(maps.Keys(m1))
File I/O
Go
12345678910111213141516171819import (
"log"
"os"
)
// Reading File
data, err := os.ReadFile("example.txt")
if err != nil {
log.Fatal(err)
}
// Writing File
err = os.WriteFile("output.txt", []byte("Hello"), 0644)
if err != nil {
log.Fatal(err)
}
// Note: ioutil was deprecated in Go 1.16; use os and io instead.
Package Management
Bash
123456789101112131415161718# Initialize a new module
go mod init example.com/myproject
# Add or update a dependency
go get example.com/some/package@latest
# Tidy up: add missing / remove unused dependencies
go mod tidy
# Show the module dependency graph
go mod graph
# Verify dependencies against go.sum
go mod verify
# Workspaces (Go 1.18+) for multi-module development
go work init ./moduleA ./moduleB
Testing
Go
12345678910111213141516171819202122232425262728293031323334353637383940414243// example_test.go
import "testing"
func TestAdd(t *testing.T) {
result := add(2, 3)
if result != 5 {
t.Errorf("Expected 5, got %d", result)
}
}
// Table-driven tests
func TestAddTable(t *testing.T) {
cases := []struct {
name string
a, b, want int
}{
{"positive", 2, 3, 5},
{"zero", 0, 0, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if got := add(c.a, c.b); got != c.want {
t.Errorf("got %d, want %d", got, c.want)
}
})
}
}
// Benchmarks
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
add(2, 3)
}
}
// Fuzz tests (Go 1.18+)
func FuzzAdd(f *testing.F) {
f.Add(1, 2)
f.Fuzz(func(t *testing.T, a, b int) {
_ = add(a, b)
})
}
Tooling
Bash
1234567891011121314go build ./... # Build everything in the module
go run ./cmd/app # Compile and run a package
go test ./... # Run all tests
go test -race ./... # Run tests with the race detector
go test -cover ./... # Test with coverage
go vet ./... # Static analysis
gofmt -w . # Format code (or `go fmt ./...`)
go doc fmt.Println # View documentation
go install example.com/cmd@latest # Install a binary
# tool directive (Go 1.24+) tracks developer tools in go.mod
go get -tool golang.org/x/tools/cmd/stringer@latest
go tool stringer ...
Best Practices
- Use
gofmt(orgo fmt) for consistent code formatting. - Prefer composition over inheritance.
- Keep functions small and focused; accept interfaces, return concrete types.
- Handle every error explicitly; wrap with
%wto preserve context. - Pass
context.Contextas the first argument of any function that does I/O or may block. - Use small, well-defined interfaces close to the consumer.
- Leverage goroutines for concurrent tasks, but guard shared state with channels or sync primitives.
- Run the race detector in CI (
go test -race ./...). - Prefer
anyoverinterface{}for new code (Go 1.18+). - Use
log/slogfor structured logging instead of the legacylogpackage for new code.
Performance Tips
- Use
sync.Poolfor object reuse in hot paths. - Minimize heap allocations; pass pointers to large structs.
- Pre-size slices and maps when capacity is known (
make([]T, 0, n)). - Benchmark with
testing.Band use-benchmemto track allocations. - Profile with
pprof(go test -cpuprofile,net/http/pprof). - Choose appropriate data structures; prefer slices over linked structures.
- Use
GOMAXPROCSand runtime metrics (runtime/metrics) to tune behavior.
Resources for Further Learning
- Official Go Documentation: https://go.dev/doc/
- A Tour of Go: https://go.dev/tour/
- Effective Go: https://go.dev/doc/effective_go
- Go by Example: https://gobyexample.com/
- Standard Library Reference: https://pkg.go.dev/std
- The Go Blog (release notes & deep dives): https://go.dev/blog/
- "The Go Programming Language" by Alan A. A. Donovan and Brian W. Kernighan
Continue Learning
Discover more cheatsheets to boost your productivity