Introduction to the GoLang Cheat Sheet

If you’re searching for a clear and practical GoLang cheat sheet, you’re in the right place. Go, or Golang, is a modern programming language developed by Google, known for its speed, simplicity, and excellent support for concurrency. It’s widely used in cloud development, backend systems, DevOps tools, and scalable web applications. This GoLang cheat sheet by Solviyo is your quick reference guide — covering everything from Go syntax and variables to advanced concepts like goroutines, channels, and interfaces. You can read it online or download the GoLang cheat sheet PDF for offline learning.

If you’re completely new to the language, we recommend starting with our beginner’s guide — Go (Golang) for Beginners: Why You Should Learn Go in 2025 . It explains why Go has become one of the most in-demand programming languages for developers, and how it’s shaping the future of backend and cloud development.

Whether you’re a beginner exploring Go for the first time or an experienced developer brushing up on the language before an interview, this guide is designed to help you learn faster. It includes easy-to-follow examples, short explanations, and practical tips — all organized into simple, digestible sections. You’ll find code snippets you can copy, real-world examples, and insights that help you write clean and efficient Go code.

This Go quick reference covers the most essential topics like data types, loops, functions, structs, slices, maps, and error handling. You’ll also find advanced sections on concurrency with goroutines and channels, Go modules, memory management, and idiomatic Go practices. Each topic is explained in plain English, so you can focus more on coding and less on searching for syntax.

For developers preparing for interviews or working on Go projects, this page doubles as a Go programming quick reference. It’s designed to help you recall syntax, commands, and best practices at a glance. And if you prefer learning offline, you can easily download the GoLang cheat sheet PDF version and keep it handy for everyday use. Bookmark this guide — it’s your complete companion for mastering Go in 2025 and beyond.

Hello Go

Installing Go

Install Go for your OS:

# Linux (Ubuntu/Debian)
sudo apt install golang-go

# macOS (Homebrew)
brew install go

# Windows (winget)
winget install Go.Go

# Verify installation
go version

Setting Up Environment

Check your Go environment and key paths:

go env

# Key variables:
# GOROOT: Go installation directory
# GOPATH: Workspace for Go projects
# GOMODCACHE: Module cache directory

Creating a Module

Initialize a module to manage dependencies:

mkdir myproject
cd myproject
go mod init github.com/username/myproject
go mod tidy

First Go Program

Create hello.go:

package main

import "fmt"

func main() {
    fmt.Println("Hello from Solviyo!")
}

Run or build:

# Run directly
go run hello.go

# Build binary
go build hello.go

Recommended Editors & Tools

  • VS Code: Go extension for syntax highlighting, debugging, and modules.
  • GoLand: Full-featured Go IDE by JetBrains.
  • Other editors: Sublime Text, Vim/Neovim, Emacs (with Go plugins).
Note: Once installed, with your first program running, you’re ready to explore Go syntax, functions, and advanced concepts quickly.

Go Syntax & Basics

Variables

Declare variables using var or short declaration :=:

// Using var
var name string = "Solviyo"
var age int = 25

// Short declaration (only inside functions)
city := "Dhaka"
count := 10

Constants

Use const for values that do not change:

const Pi = 3.14159
const AppName string = "Solviyo Go Cheat Sheet"

Primitive Types & Zero Values

Common Go types and their zero values:

var i int        // 0
var f float64    // 0.0
var b bool       // false
var s string     // ""

Type Aliases & Conversion

Define custom types or convert between types:

// Type alias
type Age int

var myAge Age = 30

// Type conversion
var x int = 10
var y float64 = float64(x)

Type Table

Type Zero Value Typical Use
int / uint 0 Counting, indexes
float32 / float64 0.0 Measurements, calculations
bool false Flags, condition checks
string "" (empty) Text, messages
Note: Go initializes variables with their zero values automatically. Use type conversion carefully to avoid runtime errors.

Go Operators & Expressions

Arithmetic Operators

Perform numeric calculations:

a, b := 10, 3

fmt.Println(a + b)  // 13
fmt.Println(a - b)  // 7
fmt.Println(a * b)  // 30
fmt.Println(a / b)  // 3
fmt.Println(a % b)  // 1

Comparison Operators

Compare values:

x, y := 5, 8

fmt.Println(x == y) // false
fmt.Println(x != y) // true
fmt.Println(x > y)  // false
fmt.Println(x < y)  // true
fmt.Println(x >= y) // false
fmt.Println(x <= y) // true

Logical Operators

Combine boolean expressions:

p, q := true, false

fmt.Println(p && q) // false
fmt.Println(p || q) // true
fmt.Println(!p)     // false

Bitwise Operators

Operate on binary representations:

var m uint = 6  // 110 in binary
var n uint = 3  // 011 in binary

fmt.Println(m & n)  // 2  (010)
fmt.Println(m | n)  // 7  (111)
fmt.Println(m ^ n)  // 5  (101)
fmt.Println(m &^ n) // 4  (100)
fmt.Println(m << 1) // 12 (1100)
fmt.Println(m >> 1) // 3  (011)

Assignment Operators

Shorthand for arithmetic + assignment:

x := 10
x += 5   // x = 15
x -= 3   // x = 12
x *= 2   // x = 24
x /= 4   // x = 6
x %= 4   // x = 2
x &= 3   // x = 2 & 3 = 2
x |= 1   // x = 2 | 1 = 3
x ^= 2   // x = 3 ^ 2 = 1
x <<= 1  // x = 1 << 1 = 2
x >>= 1  // x = 2 >> 1 = 1

Operator Precedence (Summary)

Precedence Operators Example
Highest () [] . function calls, indexing
  * / % << >> & &^ multiplication, division, bitwise
  + - | ^ addition, subtraction, bitwise OR/XOR
  == != < <= > >= comparisons
Lowest && || logical AND/OR
Note: Use parentheses () to ensure the correct evaluation order when combining multiple operators.

Go Control Flow

If Statements

Basic if and if with short statement:

x := 10

// Basic if
if x > 5 {
    fmt.Println("x is greater than 5")
}

// If with short statement
if y := x * 2; y > 15 {
    fmt.Println("y is greater than 15:", y)
}

Switch Statements

Tagless switch, fallthrough example:

day := 3

switch day {
case 1:
    fmt.Println("Monday")
case 2:
    fmt.Println("Tuesday")
case 3:
    fmt.Println("Wednesday")
    fallthrough
case 4:
    fmt.Println("Thursday")
default:
    fmt.Println("Other day")
}

// Tagless switch (like if-else chain)
switch {
case x < 0:
    fmt.Println("Negative")
case x == 0:
    fmt.Println("Zero")
default:
    fmt.Println("Positive")
}

For Loops

Classic, range, and infinite loops:

// Classic for
for i := 0; i < 5; i++ {
    fmt.Println(i)
}

// Range over slice
nums := []int{1,2,3}
for index, val := range nums {
    fmt.Println(index, val)
}

// Infinite loop
count := 0
for {
    fmt.Println("Loop", count)
    count++
    if count >= 3 { break }
}

Break, Continue, Goto

for i := 0; i < 5; i++ {
    if i == 2 {
        continue // skip iteration
    }
    if i == 4 {
        break // exit loop
    }
    fmt.Println(i)
}

// Goto example
label:
fmt.Println("Goto example")
goto label // be careful: infinite if not handled
Note: Use goto sparingly; prefer structured loops for readability. switch without a tag acts like a cleaner if-else chain.

Go Functions & Methods

Basic Functions

Declare functions with optional multiple and named return values:

// Simple function
func add(a, b int) int {
    return a + b
}

// Multiple returns
func swap(x, y string) (string, string) {
    return y, x
}

// Named returns
func split(total int) (x, y int) {
    x = total / 2
    y = total - x
    return
}

Variadic Functions & Defer

Functions with variable number of arguments and deferred execution:

// Variadic function
func sum(nums ...int) int {
    total := 0
    for _, n := range nums {
        total += n
    }
    return total
}

// Defer example
func demo() {
    defer fmt.Println("This runs last")
    fmt.Println("This runs first")
}

Methods & Receivers

Attach methods to types; use pointer vs value receivers:

type Rectangle struct {
    Width, Height float64
}

// Value receiver
func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

// Pointer receiver (can modify original)
func (r *Rectangle) Scale(factor float64) {
    r.Width *= factor
    r.Height *= factor
}

Anonymous Functions & Closures

Functions as values, closures, higher-order functions:

// Anonymous function assigned to variable
greet := func(name string) {
    fmt.Println("Hello,", name)
}
greet("Solviyo")

// Closure example
func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}
posSum := adder()
fmt.Println(posSum(5)) // 5
fmt.Println(posSum(3)) // 8

// Higher-order function
func apply(f func(int) int, value int) int {
    return f(value)
}
double := func(x int) int { return x * 2 }
fmt.Println(apply(double, 4)) // 8
Note: Go supports first-class functions. Use closures and higher-order functions for flexible and reusable code.

Go Generics (Type Parameters)

Basic Generic Functions

Generics allow functions to work with multiple types. Available since Go 1.18+:

// Generic function for swapping two values
func Swap[T any](a, b T) (T, T) {
    return b, a
}

x, y := Swap[int](1, 2)
fmt.Println(x, y) // 2 1

s1, s2 := Swap[string]("foo", "bar")
fmt.Println(s1, s2) // bar foo

Generic Types

Define generic types with type parameters:

type Pair[T any] struct {
    First, Second T
}

p := Pair[int]{First: 10, Second: 20}
fmt.Println(p.First, p.Second)

Constraints

Use constraints to restrict allowed types:

func SumIntsOrFloats[T int | float64](s []T) T {
    var total T
    for _, v := range s {
        total += v
    }
    return total
}

Type Parameter & Constraint Table

Constraint Description Example
any Accepts any type T any
comparable Types that support == and != T comparable
Specific types Restrict to a set of types T int \| float64 \| string

Best Practices

  • Use generics to reduce code duplication for similar functions/types.
  • Prefer simple constraints; avoid overcomplicating type logic.
  • Don’t use generics if normal types suffice — clarity first.
Note: Generics make Go more flexible while keeping type safety. Use them for reusable containers, utilities, and algorithms.

Go Arrays, Slices & Maps

Arrays vs Slices

Arrays have fixed length; slices are dynamic and more commonly used.

// Array
var arr [3]int
arr[0] = 1

// Slice (dynamic)
s := []int{1, 2, 3}
s = append(s, 4)
fmt.Println(s) // [1 2 3 4]

// Slice from array
sub := arr[0:2] // slicing
fmt.Println(sub)

Slice Utilities

// make to preallocate slice
numbers := make([]int, 0, 5) // len=0, cap=5

// copy slices
src := []int{1,2,3}
dst := make([]int, len(src))
copy(dst, src)
fmt.Println(dst)

Arrays vs Slices Table

Feature Array Slice
Length Fixed at compile time Dynamic, can grow with append
Capacity Same as length Can be larger than length; grows automatically
Memory Contiguous block, fixed References underlying array, dynamic allocation
Slicing Not applicable slice[start:end], shared underlying array

Maps

Maps store key-value pairs. Keys are unique.

// Create map
ages := map[string]int{"Alice": 25, "Bob": 30}

// Retrieve value
fmt.Println(ages["Alice"]) // 25

// Check existence
v, ok := ages["Charlie"]
fmt.Println(v, ok) // 0 false

// Add or update
ages["Charlie"] = 28

// Delete key
delete(ages, "Bob")

// Iterate (order is random)
for name, age := range ages {
    fmt.Println(name, age)
}
Note: Slices are preferred over arrays for flexibility. Maps do not guarantee iteration order — avoid relying on it.

Go Structs, Methods & Interfaces

Structs

Define custom types to group related fields:

type Person struct {
    Name string
    Age  int
}

// Struct literal
p := Person{Name: "Alice", Age: 30}

// Access fields
fmt.Println(p.Name, p.Age)

// Embedding (composition)
type Employee struct {
    Person
    Position string
}

e := Employee{
    Person:   Person{Name: "Bob", Age: 25},
    Position: "Developer",
}
fmt.Println(e.Name, e.Position) // inherited field

JSON Tags Example

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

Methods

Attach behavior to structs:

// Value receiver
func (p Person) Greet() string {
    return "Hello, " + p.Name
}

// Pointer receiver (can modify fields)
func (p *Person) HaveBirthday() {
    p.Age++
}

alice := Person{Name: "Alice", Age: 30}
fmt.Println(alice.Greet())
alice.HaveBirthday()
fmt.Println(alice.Age) // 31

Interfaces

Define behavior implicitly; any type implementing methods satisfies the interface:

type Greeter interface {
    Greet() string
}

func sayHello(g Greeter) {
    fmt.Println(g.Greet())
}

sayHello(alice) // Person implements Greeter

// Empty interface
var anyValue interface{}
anyValue = 42
anyValue = "Solviyo"

Common Go Interfaces Table

Interface Description Example Usage
io.Reader Anything that can read data file.Read(p []byte)
io.Writer Anything that can write data os.Stdout.Write([]byte("Hello"))
fmt.Stringer Types that can return string representation func (p Person) String() string
error Represents errors in Go return errors.New("something went wrong")

Best Practices

  • Keep interfaces small; prefer many small interfaces over one large one.
  • Use composition (embedding) instead of deep inheritance hierarchies.
  • Rely on implicit implementation rather than explicit declarations.
Note: Structs + methods + interfaces form the core of idiomatic Go. Master them to write clean, composable, and maintainable code.

Go Pointers & Memory Model

Pointer Basics

Use pointers to reference memory locations:

// Declare a variable
x := 42

// Pointer to x
ptr := &x
fmt.Println(*ptr) // Dereference, prints 42

// Modify value via pointer
*ptr = 100
fmt.Println(x)    // 100

Pointers in Functions

Pass by reference using pointers:

func increment(n *int) {
    *n++
}

val := 10
increment(&val)
fmt.Println(val) // 11

Pointers with Methods

Use pointer receivers to modify struct fields:

type Counter struct {
    Count int
}

func (c *Counter) Increase() {
    c.Count++
}

ctr := Counter{}
ctr.Increase()
fmt.Println(ctr.Count) // 1

Memory Allocation & Escape Analysis

Brief notes:

  • `new(Type)` allocates zeroed memory and returns a pointer.
  • Local variables may escape to heap if referenced outside function (Go escape analysis).
  • Pointers help reduce copies for large structs and slices.

Pointer Operators Table

Operator Usage Example
& Address-of operator ptr := &x
* Dereference operator fmt.Println(*ptr)
new(Type) Allocates memory and returns pointer p := new(int)
Note: Use pointers when you need to modify variables, avoid large copies, or interact with low-level memory efficiently.

Go Error Handling & Best Practices

Basic Error Handling

Go uses the built-in error type. Return errors from functions:

import (
    "errors"
    "fmt"
)

func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}

result, err := divide(10, 0)
if err != nil {
    fmt.Println("Error:", err)
} else {
    fmt.Println("Result:", result)
}

Error Wrapping

Wrap errors to preserve context using %w:

func readFile(path string) error {
    _, err := os.ReadFile(path)
    if err != nil {
        return fmt.Errorf("failed to read %s: %w", path, err)
    }
    return nil
}

// Check specific error
if errors.Is(err, os.ErrNotExist) {
    fmt.Println("File does not exist")
}

Panic, Recover & Defer

Use panic for unrecoverable errors; recover can catch panics:

func safeDivide(a, b int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic:", r)
        }
    }()
    if b == 0 {
        panic("division by zero")
    }
    fmt.Println("Result:", a/b)
}

safeDivide(10, 0)

Error Utilities Table

Function Purpose Example
errors.New Create a simple error errors.New("something went wrong")
fmt.Errorf Format and wrap errors fmt.Errorf("context: %w", err)
errors.Is Check error equality errors.Is(err, os.ErrNotExist)
errors.As Check and cast error type errors.As(err, &pathErr)
errors.Join Combine multiple errors (Go 1.20+) errors.Join(err1, err2)

Best Practices

  • Return errors instead of panicking for recoverable situations.
  • Use defer + recover only for top-level recovery, not normal flow control.
  • Log errors at the boundary (main function or handler), pass context with wrapping.
  • Small, descriptive error messages improve debugging and API clarity.
Note: Idiomatic Go emphasizes explicit error handling. Use panic sparingly, prefer returning and wrapping errors, and utilize errors.Is/errors.As for precise handling.

Go Concurrency — Goroutines, Channels & Patterns

Goroutines

Goroutines are lightweight threads managed by the Go runtime. Launch a goroutine using the go keyword. They run concurrently, allowing efficient scaling without heavy OS threads.

func sayHello() {
    fmt.Println("Hello from Goroutine")
}

// Launch goroutine
go sayHello()

// Wait for goroutines using sync.WaitGroup
var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    fmt.Println("Task completed")
}()
wg.Wait()

Channels

Channels provide a safe way for goroutines to communicate. They can be unbuffered or buffered.

// Unbuffered channel
ch := make(chan int)
go func() { ch <- 42 }()
val := <-ch
fmt.Println(val) // 42

// Buffered channel
buf := make(chan string, 2)
buf <- "foo"
buf <- "bar"
fmt.Println(<-buf, <-buf)

// Close channel and range over values
close(buf)
for v := range buf {
    fmt.Println(v)
}

Channel Types

Channel Type Description Example
Unbuffered Sender blocks until receiver is ready ch := make(chan int)
Buffered Sender can send without blocking until buffer is full ch := make(chan int, 5)
Closed No more values can be sent; receivers get zero value close(ch)

Select Statement & Timeouts

The select statement allows waiting on multiple channel operations simultaneously. It is also used for non-blocking communication and timeouts.

select {
case msg := <-ch:
    fmt.Println("Received", msg)
case <-time.After(2 * time.Second):
    fmt.Println("Timeout reached")
default:
    fmt.Println("No channel activity")
}

Select Statement Patterns

Pattern Description Example
Receive Wait for value from channel case msg := <-ch:
Timeout Exit if channel doesn’t respond in time case <-time.After(2 * time.Second):
Default Non-blocking select default:

Synchronization Primitives

Use synchronization primitives when channels are insufficient for shared memory access.

var mu sync.Mutex
counter := 0

// Protect shared resource
mu.Lock()
counter++
mu.Unlock()

// Atomic operations
import "sync/atomic"
atomic.AddInt32(&counter32, 1)

Synchronization Primitives Table

Primitive Purpose Example
sync.Mutex Lock/unlock shared memory mu.Lock(); counter++; mu.Unlock()
sync.RWMutex Read-write lock for concurrent reads rw.RLock(); ...; rw.RUnlock()
sync/atomic Atomic operations on primitives atomic.AddInt32(&counter32, 1)

Common Concurrency Patterns

  • Worker Pools: Multiple goroutines process jobs from a channel efficiently.
  • Pipeline Pattern: Chain goroutines to process streams step by step.
  • Worker per CPU: One goroutine per CPU core for CPU-bound tasks.
  • Rate Limiting: Limit concurrency using buffered channels or time.Ticker.
  • Context Cancellation: Use context.Context to stop goroutines gracefully and avoid leaks.

Concurrency Patterns Table

Pattern Description Example / Notes
Worker Pool Multiple goroutines process jobs from a channel jobs := make(chan Job, 10)
Pipeline Sequential data processing in stages Stage1 -> Stage2 -> Stage3 via channels
Context Cancellation Stop goroutines gracefully ctx, cancel := context.WithCancel(parentCtx)
Rate Limiting Control number of concurrent operations Buffered channels or time.Ticker

Tools & Best Practices

  • Detect race conditions: go test -race
  • Avoid goroutine leaks: always close channels or cancel context.
  • Prefer channels for communication; use mutexes only for shared memory.
  • Keep goroutines short-lived; avoid blocking operations without timeout.
  • Use select with time.After and default cases for non-blocking operations.
Note: Concurrency is one of Go's strongest features. Master goroutines, channels, select statements, synchronization primitives, and context cancellation to build scalable, safe, and high-performance applications.

Go Packages, Modules & Dependency Management

Module Lifecycle

Modules are the standard way to manage dependencies in modern Go. Use go mod commands to initialize, tidy, and manage dependencies.

# Initialize a new module
go mod init github.com/username/myproject

# Tidy dependencies (add missing, remove unused)
go mod tidy

# Add or update a dependency
go get github.com/gin-gonic/gin@v1.9.0

Semantic Import Versioning & Replace

For modules with major version v2+, the import path must include the version suffix. Use replace directive for local development:

// go.mod example
module github.com/username/myproject/v2

go 1.21

require github.com/gin-gonic/gin v1.9.0

// Replace local copy for testing
replace github.com/gin-gonic/gin => ../gin

GOPROXY, Caching & Vendoring

Go modules use a proxy and cache for reliable builds. Vendoring copies dependencies locally for reproducible builds:

# Set proxy
export GOPROXY=https://proxy.golang.org,direct

# Verify module cache
go env GOMODCACHE

# Create vendor directory
go mod vendor

Module Commands Table

Command Purpose Example
go mod init Create a new module go mod init github.com/username/myproject
go mod tidy Add missing, remove unused dependencies go mod tidy
go get Add or update dependency go get github.com/gin-gonic/gin@v1.9.0
go mod vendor Copy dependencies locally go mod vendor
replace Use local module path instead of remote replace github.com/gin-gonic/gin => ../gin
Note: Using Go modules ensures reproducible builds, proper versioning, and easier collaboration. Always run go mod tidy after adding or removing dependencies.

Go Standard Library Highlights — Practical Picks

net/http — Quick Server & Client

Build HTTP servers and clients quickly with the standard library.

// Simple HTTP server
package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello from Solviyo!")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

// Simple HTTP client
resp, err := http.Get("http://localhost:8080")
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

encoding/json — Marshal & Unmarshal

Convert structs to/from JSON with struct tags:

type User struct {
    Name  string `json:"name"`
    Email string `json:"email"`
}

user := User{Name: "Alice", Email: "alice@example.com"}

// Marshal to JSON
data, _ := json.Marshal(user)
fmt.Println(string(data))

// Unmarshal from JSON
var u User
_ = json.Unmarshal(data, &u)
fmt.Println(u.Name, u.Email)

File & Stream Handling — io, bufio, os

Reading & writing files efficiently:

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

// Read file line by line
file, _ := os.Open("input.txt")
defer file.Close()

scanner := bufio.NewScanner(file)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}

// Write file
out, _ := os.Create("output.txt")
defer out.Close()
out.WriteString("Hello Solviyo!\n")

time & context Utilities

Use time for durations, sleep, and timestamps; context for cancellation and deadlines:

import (
    "context"
    "fmt"
    "time"
)

// Timeout with context
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

select {
case <-time.After(3 * time.Second):
    fmt.Println("Task done")
case <-ctx.Done():
    fmt.Println("Timeout reached:", ctx.Err())
}

Standard Library Quick Reference Table

Package Use Case Example
net/http HTTP server & client http.HandleFunc("/", handler)
encoding/json JSON marshal/unmarshal json.Marshal(u), json.Unmarshal(data, &u)
io, bufio, os File and stream handling bufio.NewScanner(file), os.Create("out.txt")
time Durations, sleep, timestamps time.Sleep(2*time.Second)
context Cancellation, deadlines context.WithTimeout(parentCtx, 2*time.Second)
Note: These standard library packages cover the most common tasks in Go. They are fast, reliable, and eliminate the need for many external dependencies.

Go File I/O & Networking Examples

File I/O — Read & Write

Handle files efficiently using os and bufio. Examples include reading line by line, writing, and streaming large files.

import (
    "bufio"
    "fmt"
    "os"
)

// Reading a file line by line
file, _ := os.Open("input.txt")
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}

// Writing to a file
out, _ := os.Create("output.txt")
defer out.Close()
out.WriteString("Hello Solviyo!\n")

// Streaming large files
in, _ := os.Open("largefile.dat")
defer in.Close()
outFile, _ := os.Create("copy.dat")
defer outFile.Close()
buf := make([]byte, 1024*4) // 4KB buffer
for {
    n, err := in.Read(buf)
    if n > 0 {
        outFile.Write(buf[:n])
    }
    if err != nil {
        break
    }
}

Networking — Basic HTTP Server

Create a minimal HTTP server with routing and handlers.

import (
    "fmt"
    "log"
    "net/http"
)

// Handler function
func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello from Solviyo!")
}

// Custom route
func aboutHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "About Solviyo")
}

func main() {
    http.HandleFunc("/", helloHandler)
    http.HandleFunc("/about", aboutHandler)
    log.Println("Server running at :8080")
    http.ListenAndServe(":8080", nil)
}

File & Networking Quick Reference Table

Task Package / Function Example
Read file line by line os + bufio scanner := bufio.NewScanner(file)
Write to file os.File.WriteString out.WriteString("Hello")
Stream large files os.File.Read buf := make([]byte, 4096)
Basic HTTP server net/http http.HandleFunc("/", handler)
Routing http.HandleFunc http.HandleFunc("/about", aboutHandler)
Note: Use buffered I/O for large files to optimize memory usage. For networking, always handle errors and consider graceful shutdown in production servers.

Go Testing, Benchmarking & Quality Tools

Unit Testing Basics

Use go test to run tests. Table-driven tests are common in Go for multiple input/output cases.

import "testing"

// Function to test
func Add(a, b int) int {
    return a + b
}

// Table-driven test
func TestAdd(t *testing.T) {
    tests := []struct {
        name string
        a, b int
        want int
    }{
        {"1+2", 1, 2, 3},
        {"5+7", 5, 7, 12},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got := Add(tt.a, tt.b)
            if got != tt.want {
                t.Errorf("Add(%d,%d) = %d, want %d", tt.a, tt.b, got, tt.want)
            }
        })
    }
}

Benchmarking

Measure performance of functions using testing.B:

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = Add(100, 200)
    }
}

// Run benchmark:
// go test -bench=.

Profiling with pprof

Capture CPU and memory profiles:

import (
    "net/http"
    _ "net/http/pprof"
)

func main() {
    go func() {
        log.Println(http.ListenAndServe("localhost:6060", nil))
    }()
    // your application code
}

Quality Tools Quick Reference

Tool Purpose Example / Command
go vet Check code correctness and common mistakes go vet ./...
gofmt Automatically format code gofmt -w main.go
golangci-lint Run multiple linters in one tool golangci-lint run
delve Debugger for Go dlv debug main.go
pprof CPU / memory profiling go tool pprof cpu.prof
testing.B Benchmark functions go test -bench=.
Note: Regularly run tests, benchmarks, and linters to maintain high code quality. Table-driven tests are idiomatic in Go and make testing multiple cases concise.

Go Performance & Profiling Tips

CPU & Memory Profiling with pprof

Use pprof to analyze performance bottlenecks:

import (
    "log"
    "net/http"
    _ "net/http/pprof"
)

func main() {
    go func() {
        log.Println(http.ListenAndServe("localhost:6060", nil))
    }()

    // Your application code
}

// Run the program and use:
// go tool pprof http://localhost:6060/debug/pprof/profile
// go tool pprof http://localhost:6060/debug/pprof/heap

Memory Optimization

Reduce allocations and reuse buffers efficiently:

import "sync"

var bufPool = sync.Pool{
    New: func() interface{} {
        return make([]byte, 4096)
    },
}

func processData(data []byte) {
    buf := bufPool.Get().([]byte)
    defer bufPool.Put(buf)
    // use buf for temporary processing
}

Benchmarking Patterns

Use testing.B to identify slow functions and interpret results:

func BenchmarkProcessData(b *testing.B) {
    data := make([]byte, 1024)
    for i := 0; i < b.N; i++ {
        processData(data)
    }
}

// Run with:
// go test -bench=.

Performance Quick Reference Table

Task Tool / Pattern Example / Notes
CPU profiling pprof go tool pprof http://localhost:6060/debug/pprof/profile
Memory profiling pprof go tool pprof http://localhost:6060/debug/pprof/heap
Reduce allocations sync.Pool buf := bufPool.Get()
Benchmark functions testing.B go test -bench=.
Buffer reuse slice reuse Use pooled slices instead of new allocations
Note: Combining profiling, benchmarking, and memory pooling allows you to write highly efficient Go code while avoiding common performance pitfalls.

Go Build, Cross-compilation & Deployment

Cross-compilation

Go makes it easy to build binaries for other platforms using GOOS and GOARCH environment variables.

# Build Linux binary on macOS
GOOS=linux GOARCH=amd64 go build -o myapp-linux

# Build Windows binary on Linux
GOOS=windows GOARCH=386 go build -o myapp.exe

# Check available architectures
go tool dist list

Static Binaries

Create self-contained binaries for deployment:

# Static binary for Linux
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags="-s -w" -o myapp

Building & Running with Docker

Use multi-stage Docker builds for small, portable images:

# Stage 1: Build
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# Stage 2: Minimal image
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]

CI/CD Snippet Example

GitHub Actions example to build and test:

name: Go CI

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: 1.21
      - name: Build
        run: go build -v ./...
      - name: Test
        run: go test -v ./...

Build & Deployment Quick Reference Table

Task Command / Tool Notes
Cross-compile GOOS & GOARCH GOOS=linux GOARCH=amd64 go build
Static binary CGO_ENABLED=0 go build -a -ldflags="-s -w"
Docker build Multi-stage Dockerfile Use builder + minimal runtime image
CI/CD GitHub Actions Set up Go, build & test automatically
Note: Go's static binaries and cross-compilation make deployment simple. Combine with Docker and CI/CD for reliable production workflows.

Advanced Go Topics — Quick Reference

Reflection (`reflect`)

Use reflection to inspect types and values at runtime. Use sparingly — it can be slower and less safe.

import (
    "fmt"
    "reflect"
)

var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x))
fmt.Println("value:", reflect.ValueOf(x))

cgo — Interoperability with C

Allows calling C code from Go. Useful but adds complexity and may reduce portability.

/*
#include 
#include 
*/
import "C"

func main() {
    C.puts(C.CString("Hello from C via Go!"))
}

Build Tags & Conditional Compilation

Use build tags to include/exclude files for specific platforms or conditions.

// +build linux

package main
func main() {
    println("This file compiles only on Linux")
}

Embed Files (`embed` package)

Embed static files directly into your binary using go:embed:

import (
    _ "embed"
    "fmt"
)

//go:embed hello.txt
var helloText string

func main() {
    fmt.Println(helloText)
}

Advanced Topics Quick Reference Table

Feature Purpose Example
Reflection Inspect types & values at runtime reflect.TypeOf(x), reflect.ValueOf(x)
cgo Call C functions from Go C.puts(C.CString("Hello"))
Build Tags Conditional compilation for platforms // +build linux
Embed Include files in binary //go:embed hello.txt
Note: Advanced topics are powerful but should be used carefully. Reflection and cgo can affect performance and portability, while build tags and embed increase flexibility.

Go Security & Best Practices

Input Validation & Sanitization

Validate and sanitize inputs to prevent injection and unexpected behavior. Use proper escaping for HTML or URL contexts.

package main

import (
    "fmt"
    "html"
    "net/url"
)

// Escape for HTML output
func escapeForHTML(s string) string {
    return html.EscapeString(s)
}

// Escape for URL/query parameter
func escapeForURL(s string) string {
    return url.QueryEscape(s)
}

func main() {
    raw := `Hello  & "special" chars?`
    fmt.Println("HTML escaped:", escapeForHTML(raw))
    fmt.Println("URL escaped:", escapeForURL(raw))
}

Secure JSON Handling

Use concrete structs for JSON input and avoid unmarshalling into map[string]interface{} unless you explicitly need dynamic schemas.

package main

import (
    "encoding/json"
    "log"
)

type User struct {
    Name  string `json:"name"`
    Email string `json:"email"`
}

func main() {
    data := []byte(`{"name":"Alice","email":"alice@example.com"}`)
    var u User
    if err := json.Unmarshal(data, &u); err != nil {
        log.Fatal("invalid JSON:", err)
    }
    log.Printf("User: %#v\n", u)
}

TLS & Secure Communication

Use HTTPS/TLS in production. For local testing, use self-signed certs but avoid sending sensitive data over plain HTTP.

package main

import (
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello — secure server"))
    })

    // Use ListenAndServeTLS with valid cert/key in production.
    log.Println("Starting secure server on :8443")
    log.Fatal(http.ListenAndServeTLS(":8443", "server.crt", "server.key", nil))
}

Secrets Management

Do not hardcode secrets. Read them from environment variables or use a secrets manager.

package main

import (
    "fmt"
    "os"
)

func main() {
    apiKey := os.Getenv("API_KEY")
    if apiKey == "" {
        fmt.Println("WARNING: API_KEY not set")
        // In production, fail fast or use secure default handling
    } else {
        fmt.Println("API key loaded from environment")
    }
}

Preventing Unsafe DOM Injection (Client-side note)

If your Go backend returns user-controlled data to a web page, always ensure the frontend inserts it safely:

// BAD: vulnerable to executing HTML or scripts
element.innerHTML = userProvidedString;

// GOOD: render as plain text (safe)
element.textContent = userProvidedString;

Security Quick Reference Table

Task Practice Notes
Input sanitization html.EscapeString, url.QueryEscape Escape for the specific output context (HTML vs URL).
JSON handling Use strict structs + json.Unmarshal Avoid generic maps unless intentionally required.
TLS / HTTPS http.ListenAndServeTLS Always use TLS in production; protect certificates.
Secrets Environment variables, vaults Never commit keys or passwords to source control.
Note: Use context-aware escaping (HTML vs URL vs SQL). Combine server-side escaping with safe client-side rendering (use textContent, not innerHTML) to prevent XSS.

Common Go Commands — Quick Reference

This table summarizes the most frequently used Go commands for daily development, building, testing, and formatting.

Command Description Example Usage
go run Compile and run Go files in one step go run main.go
go build Compile Go code into a binary go build -o myapp main.go
go test Run unit tests go test ./...
go fmt Automatically format Go source code go fmt ./...
go vet Analyze code for potential errors or suspicious constructs go vet ./...
go install Compile and install a package or binary to GOPATH/bin go install github.com/user/myapp@latest
go mod init Initialize a new module in the project go mod init github.com/user/myproject
go mod tidy Clean up module dependencies go mod tidy
go get Add or update a dependency go get github.com/pkg/errors
Note: Keep this table handy — these commands are the backbone of everyday Go development. Most developers refer to it multiple times per project.

Quick Patterns & Idioms — Go Cheat Cards

This section highlights common idiomatic Go patterns and best practices to write clean, maintainable, and idiomatic code.

Common Idioms

  • Zero Value: Go variables are automatically initialized to their zero value (0, "", false, nil). Take advantage of this instead of explicit initialization.
  • Small Interfaces: Prefer defining small, focused interfaces rather than large ones.
  • Error Handling Idiom: Return error and handle it immediately with if err != nil.
  • Slices over Arrays: Use slices for flexible, resizable lists.
  • Defer for Cleanup: Use defer to close files, connections, or release resources.
  • For Range Loops: Use for i, v := range collection instead of traditional loops when iterating over slices, maps, or channels.
  • Composition over Inheritance: Prefer embedding structs instead of relying on inheritance.
  • Minimalistic Error Logging: Log only essential information, avoid panics in production unless unavoidable.

Quick Reference Table

Pattern Description Example
Zero Value Default initialization var count int // count == 0
Small Interfaces Keep interfaces focused type Reader interface { Read(p []byte) (n int, err error) }
Error Handling Idiomatic Go error check if err != nil { return err }
Slices over Arrays Flexible lists nums := []int{1,2,3}
Defer Automatic cleanup defer file.Close()
Composition Embed instead of inherit type Logger struct { io.Writer }
Note: Following idiomatic Go patterns improves readability, maintainability, and helps you write code that other Go developers can quickly understand and extend.

Conclusion & Further Reading

Congratulations! You’ve gone through the ultimate Go (Golang) cheat sheet. By now, you should have a solid understanding of Go syntax, data structures, concurrency patterns, modules, testing, and advanced topics. Remember, the best way to master Go is through practice — build projects, experiment with goroutines, and explore the standard library.

Internal Resources

External Resources

Note: Bookmark this cheat sheet and revisit sections as you build Go projects. Combine this with official docs and tutorials to deepen your understanding and stay updated with Go in 2025.