Go Cheat Sheet

A comprehensive Go (Golang) reference guide with syntax, examples, and usage instructions. Find the Go concepts, functions, goroutines, channels, and commands you need using the search bar or browse by category.

25 concepts found
Filter by category:

Variables

Basic Syntax

Declare and initialize variables in Go

Syntax:

var name type = value name := value // short declaration

Examples:

var name string = "John" Explicit type declaration
age := 25 Short variable declaration
var x, y int = 10, 20 Multiple variable declaration
var ( name = "Alice" age = 30 ) Variable block declaration

Notes:

Go is statically typed. Use := for new variables, = for existing ones

Constants

Basic Syntax

Declare constants in Go

Syntax:

const NAME = value const NAME type = value

Examples:

const Pi = 3.14159 Simple constant
const MaxUsers int = 100 Typed constant
const ( Red = "red" Green = "green" Blue = "blue" ) Constant block
const ( A = iota // 0 B // 1 C // 2 ) Using iota for enumeration

Notes:

Constants are computed at compile time and cannot be changed

Functions

Basic Syntax

Define and call functions in Go

Syntax:

func name(param type) returnType { return value }

Examples:

func greet(name string) string { return "Hello, " + name } Simple function with return
func add(a, b int) int { return a + b } Function with multiple parameters
func divide(a, b float64) (float64, error) { if b == 0 { return 0, errors.New("division by zero") } return a / b, nil } Function with multiple return values
func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total } Variadic function

Notes:

Functions are first-class citizens and can return multiple values

Structs

Basic Syntax

Define custom types using structs

Syntax:

type Name struct { field1 type1 field2 type2 }

Examples:

type Person struct { Name string Age int } Basic struct definition
p := Person{Name: "Alice", Age: 30} Struct initialization
type User struct { ID int `json:"id"` Username string `json:"username"` Email string `json:"email"` } Struct with JSON tags
func (p Person) Greet() string { return "Hello, I'm " + p.Name } Method on struct

Notes:

Structs are value types and support methods and tags for serialization

Packages

Basic Syntax

Organize code using packages

Syntax:

package name import "package/path"

Examples:

package main import "fmt" func main() { fmt.Println("Hello, World!") } Main package with import
import ( "fmt" "os" "time" ) Multiple imports
import ( f "fmt" _ "github.com/lib/pq" ) Import alias and blank import
package utils // Exported function (capitalized) func FormatName(s string) string { return strings.Title(s) } // unexported function func helper() {} Package with exported/unexported functions

Notes:

Capitalized names are exported (public), lowercase names are private to package

Arrays & Slices

Data Types

Work with arrays and slices in Go

Syntax:

var arr [size]type var slice []type slice := make([]type, len, cap)

Examples:

var arr [3]int = [3]int{1, 2, 3} Array declaration and initialization
slice := []string{"apple", "banana", "cherry"} Slice literal
nums := make([]int, 5, 10) fmt.Println(len(nums), cap(nums)) // 5, 10 Creating slice with make
slice = append(slice, "date") slice = append(slice, "elderberry", "fig") Appending to slice
subSlice := slice[1:3] // elements 1 and 2 Slice operations

Notes:

Arrays have fixed size, slices are dynamic. Use slices for most cases

Maps

Data Types

Use maps for key-value pairs

Syntax:

var m map[keyType]valueType m := make(map[keyType]valueType)

Examples:

ages := map[string]int{ "Alice": 30, "Bob": 25, } Map literal
m := make(map[string]int) m["key"] = 42 Creating and setting map values
value, ok := m["key"] if ok { fmt.Println("Found:", value) } Checking if key exists
delete(m, "key") // Remove key-value pair Deleting from map
for key, value := range ages { fmt.Printf("%s: %d\n", key, value) } Iterating over map

Notes:

Maps are reference types and must be initialized before use

Interfaces

Data Types

Define interfaces for polymorphism

Syntax:

type InterfaceName interface { Method1() returnType Method2(param type) returnType }

Examples:

type Writer interface { Write([]byte) (int, error) } Simple interface definition
type Shape interface { Area() float64 Perimeter() float64 } Interface with multiple methods
func (r Rectangle) Area() float64 { return r.Width * r.Height } // Rectangle implements Shape interface Implementing interface implicitly
var s Shape = Rectangle{Width: 10, Height: 5} area := s.Area() // Polymorphism Using interface for polymorphism
func describe(i interface{}) { fmt.Printf("Type: %T, Value: %v\n", i, i) } Empty interface (any type)

Notes:

Interfaces are implemented implicitly. Empty interface{} accepts any type

Pointers

Data Types

Work with memory addresses using pointers

Syntax:

var p *type p = &variable value := *p

Examples:

var p *int x := 42 p = &x fmt.Println(*p) // 42 Basic pointer usage
func increment(x *int) { *x++ } num := 5 increment(&num) fmt.Println(num) // 6 Passing pointer to function
p := new(int) // Allocates memory, returns pointer *p = 100 Using new() to allocate memory
type Person struct { Name string } p := &Person{Name: "Alice"} Pointer to struct

Notes:

Go has pointers but no pointer arithmetic. Use & to get address, * to dereference

Goroutines

Concurrency

Run functions concurrently using goroutines

Syntax:

go function() go func() { }()

Examples:

go fmt.Println("Hello from goroutine") Simple goroutine
go func() { fmt.Println("Anonymous goroutine") }() Anonymous function goroutine
for i := 0; i < 3; i++ { go func(id int) { fmt.Printf("Worker %d\n", id) }(i) } Multiple goroutines with parameters
var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() fmt.Println("Work done") }() wg.Wait() Using WaitGroup to wait for goroutines

Notes:

Goroutines are lightweight threads managed by Go runtime. Always ensure proper synchronization

Channels

Concurrency

Communicate between goroutines using channels

Syntax:

ch := make(chan type) ch := make(chan type, bufferSize) // buffered

Examples:

ch := make(chan string) go func() { ch <- "Hello" }() msg := <-ch fmt.Println(msg) Basic channel communication
ch := make(chan int, 2) // Buffered channel ch <- 1 ch <- 2 fmt.Println(<-ch, <-ch) Buffered channel
ch := make(chan int) close(ch) val, ok := <-ch fmt.Println(val, ok) // 0, false Closing channels and checking status
for val := range ch { fmt.Println(val) } Ranging over channel
ch := make(chan<- int) // Send-only ch2 := make(<-chan int) // Receive-only Directional channels

Notes:

Channels enable safe communication between goroutines. Use buffered channels to avoid blocking

Select Statement

Concurrency

Handle multiple channel operations

Syntax:

select { case <-ch1: // handle case ch2 <- value: // handle default: // default case }

Examples:

select { case msg := <-ch1: fmt.Println("Received:", msg) case <-time.After(1 * time.Second): fmt.Println("Timeout") } Select with timeout
select { case ch1 <- value: fmt.Println("Sent to ch1") case ch2 <- value: fmt.Println("Sent to ch2") default: fmt.Println("No channels ready") } Non-blocking select with default
for { select { case msg := <-ch: process(msg) case <-quit: return } } Select in infinite loop

Notes:

Select lets goroutines wait on multiple channel operations. Default case makes it non-blocking

Mutex

Concurrency

Synchronize access to shared resources

Syntax:

var mu sync.Mutex mu.Lock() defer mu.Unlock()

Examples:

type Counter struct { mu sync.Mutex value int } func (c *Counter) Increment() { c.mu.Lock() defer c.mu.Unlock() c.value++ } Using mutex for thread-safe operations
var mu sync.RWMutex func read() { mu.RLock() defer mu.RUnlock() // Read operation } Read-write mutex for concurrent reads
var once sync.Once func initialize() { once.Do(func() { fmt.Println("Initialized once") }) } Using sync.Once for one-time initialization

Notes:

Always use defer to unlock mutex. RWMutex allows multiple readers or one writer

Error Handling

Error Handling

Handle errors in Go using the error interface

Syntax:

if err != nil { // handle error }

Examples:

result, err := someFunction() if err != nil { log.Fatal(err) } Basic error checking
import "errors" func divide(a, b float64) (float64, error) { if b == 0 { return 0, errors.New("division by zero") } return a / b, nil } Creating custom errors
import "fmt" type ValidationError struct { Field string Value string } func (e *ValidationError) Error() string { return fmt.Sprintf("validation failed for %s: %s", e.Field, e.Value) } Custom error type
err := someFunction() if err != nil { return fmt.Errorf("failed to process: %w", err) } Error wrapping with fmt.Errorf

Notes:

Errors are values, not exceptions. Always check and handle errors explicitly

Panic & Recover

Error Handling

Handle exceptional conditions with panic and recover

Syntax:

panic("message") defer func() { if r := recover(); r != nil { // handle panic } }()

Examples:

func safeDivide(a, b int) (result int) { defer func() { if r := recover(); r != nil { result = 0 } }() return a / b } Using recover to handle panic
if x < 0 { panic("x cannot be negative") } Using panic for unrecoverable errors
func cleanup() { if r := recover(); r != nil { fmt.Printf("Recovered from panic: %v\n", r) // Perform cleanup } } func main() { defer cleanup() panic("Something went wrong") } Panic with cleanup using defer

Notes:

Use panic for programmer errors, not for normal error handling. Recover only works inside deferred functions

HTTP Server

HTTP & Web

Create HTTP servers using net/http package

Syntax:

http.HandleFunc("/path", handler) http.ListenAndServe(":port", nil)

Examples:

import "net/http" func hello(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, World!") } func main() { http.HandleFunc("/", hello) http.ListenAndServe(":8080", nil) } Basic HTTP server
func apiHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"message": "Hello API"}) } JSON API endpoint
mux := http.NewServeMux() mux.HandleFunc("/users", usersHandler) mux.HandleFunc("/posts", postsHandler) http.ListenAndServe(":8080", mux) Using custom mux for routing
server := &http.Server{ Addr: ":8080", Handler: mux, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, } server.ListenAndServe() HTTP server with timeouts

Notes:

net/http package provides a complete HTTP server implementation

HTTP Client

HTTP & Web

Make HTTP requests using net/http package

Syntax:

resp, err := http.Get(url) resp, err := http.Post(url, contentType, body)

Examples:

resp, err := http.Get("https://api.example.com/data") if err != nil { log.Fatal(err) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) Simple GET request
data := strings.NewReader(`{"name": "John"}`) resp, err := http.Post("https://api.example.com/users", "application/json", data) POST request with JSON
client := &http.Client{ Timeout: 30 * time.Second, } resp, err := client.Get(url) HTTP client with timeout
req, _ := http.NewRequest("PUT", url, body) req.Header.Set("Authorization", "Bearer token") req.Header.Set("Content-Type", "application/json") resp, err := client.Do(req) Custom request with headers

Notes:

Always close response body and handle timeouts for production code

JSON Handling

HTTP & Web

Work with JSON data using encoding/json

Syntax:

json.Marshal(v) json.Unmarshal(data, &v)

Examples:

type User struct { ID int `json:"id"` Name string `json:"name"` } user := User{ID: 1, Name: "Alice"} data, _ := json.Marshal(user) Marshal struct to JSON
jsonStr := `{"id": 1, "name": "Bob"}` var user User err := json.Unmarshal([]byte(jsonStr), &user) Unmarshal JSON to struct
encoder := json.NewEncoder(w) // w is io.Writer encoder.Encode(user) Stream encoding to writer
decoder := json.NewDecoder(r) // r is io.Reader var user User err := decoder.Decode(&user) Stream decoding from reader

Notes:

Use struct tags to control JSON field names. Marshal/Unmarshal for []byte, Encode/Decode for streams

Unit Tests

Testing

Write unit tests using the testing package

Syntax:

func TestName(t *testing.T) { // test code }

Examples:

func TestAdd(t *testing.T) { result := Add(2, 3) if result != 5 { t.Errorf("Add(2, 3) = %d; want 5", result) } } Basic unit test
func TestDivide(t *testing.T) { _, err := Divide(10, 0) if err == nil { t.Error("Expected error for division by zero") } } Testing error conditions
func TestMultiple(t *testing.T) { tests := []struct { a, b, want int }{ {2, 3, 6}, {4, 5, 20}, {0, 10, 0}, } for _, tt := range tests { got := Multiply(tt.a, tt.b) if got != tt.want { t.Errorf("Multiply(%d, %d) = %d; want %d", tt.a, tt.b, got, tt.want) } } } Table-driven tests

Notes:

Run tests with 'go test'. Test files must end with _test.go

Benchmarks

Testing

Write performance benchmarks

Syntax:

func BenchmarkName(b *testing.B) { for i := 0; i < b.N; i++ { // code to benchmark } }

Examples:

func BenchmarkFibonacci(b *testing.B) { for i := 0; i < b.N; i++ { Fibonacci(20) } } Basic benchmark
func BenchmarkStringBuilder(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { var sb strings.Builder for j := 0; j < 100; j++ { sb.WriteString("hello") } _ = sb.String() } } Benchmark with timer reset
func BenchmarkSort(b *testing.B) { data := make([]int, 1000) b.ResetTimer() for i := 0; i < b.N; i++ { b.StopTimer() copy(data, originalData) b.StartTimer() sort.Ints(data) } } Benchmark with setup excluded from timing

Notes:

Run benchmarks with 'go test -bench=.'. Use b.ResetTimer() to exclude setup time

Go Modules

Package Management

Manage dependencies using Go modules

Syntax:

go mod init module-name go mod tidy go get package@version

Examples:

go mod init github.com/user/project Initialize new module
go get github.com/gin-gonic/gin Add dependency
go get github.com/gin-gonic/gin@v1.9.1 Add specific version
go mod tidy Clean up dependencies
go mod download Download dependencies
go list -m all List all dependencies

Notes:

Go modules are the official dependency management system since Go 1.11

Go CLI Commands

Package Management

Common Go command line operations

Syntax:

go command [arguments]

Examples:

go run main.go Run Go program directly
go build -o myapp main.go Build executable
go install github.com/user/tool@latest Install Go program
go test ./... Run all tests recursively
go test -v -cover Run tests with verbose output and coverage
go fmt ./... Format all Go files
go vet ./... Static analysis of code

Notes:

Go CLI provides comprehensive tooling for development, testing, and deployment

Gin Framework

Popular Libraries

HTTP web framework for building APIs

Syntax:

import "github.com/gin-gonic/gin"

Examples:

r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{"message": "pong"}) }) r.Run(":8080") Basic Gin server
r.POST("/users", func(c *gin.Context) { var user User if err := c.ShouldBindJSON(&user); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } c.JSON(201, user) }) POST endpoint with JSON binding
r.GET("/users/:id", func(c *gin.Context) { id := c.Param("id") c.JSON(200, gin.H{"user_id": id}) }) URL parameters
r.Use(gin.Logger()) r.Use(gin.Recovery()) r.Use(corsMiddleware()) Middleware usage

Notes:

Gin is a high-performance HTTP framework with minimal memory footprint

Echo Framework

Popular Libraries

Minimalist web framework for Go

Syntax:

import "github.com/labstack/echo/v4"

Examples:

e := echo.New() e.GET("/", func(c echo.Context) error { return c.String(http.StatusOK, "Hello, World!") }) e.Logger.Fatal(e.Start(":8080")) Basic Echo server
e.POST("/users", func(c echo.Context) error { u := new(User) if err := c.Bind(u); err != nil { return err } return c.JSON(http.StatusCreated, u) }) POST with data binding
e.GET("/users/:id", func(c echo.Context) error { id := c.Param("id") return c.JSON(http.StatusOK, map[string]string{"id": id}) }) URL parameters with Echo
e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.Use(middleware.CORS()) Echo middleware

Notes:

Echo is optimized for high performance and extensibility with rich middleware ecosystem

GORM ORM

Popular Libraries

Object Relational Mapping library for Go

Syntax:

import "gorm.io/gorm"

Examples:

import "gorm.io/driver/sqlite" db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) db.AutoMigrate(&User{}) Database connection and migration
user := User{Name: "Alice", Email: "alice@example.com"} result := db.Create(&user) Create record
var user User db.First(&user, 1) // find by primary key db.First(&user, "name = ?", "Alice") // find by condition Query records
db.Model(&user).Update("name", "Bob") db.Model(&user).Updates(User{Name: "Bob", Age: 30}) Update records
var users []User db.Where("age > ?", 18).Find(&users) db.Order("age desc").Limit(10).Find(&users) Advanced queries

Notes:

GORM provides a full-featured ORM with auto-migration, associations, and hooks

Go Programming Tips

Best Practices

  • Follow effective Go guidelines - use gofmt, goimports, and go vet
  • Handle errors explicitly - avoid ignoring them with blank identifier
  • Use goroutines for concurrency, not for parallelism by default
  • Prefer composition over inheritance - use interfaces and embedding
  • Keep interfaces small - prefer many small interfaces over few large ones

Performance Tips

  • Use slices instead of arrays for better performance and flexibility
  • Pre-allocate slices and maps when size is known using make()
  • Use string builder for concatenating multiple strings efficiently
  • Avoid creating goroutines in tight loops - use worker pools instead
  • Use buffered channels to reduce goroutine blocking

Go Concurrency Patterns

Channel Patterns

  • Pipeline: Chain goroutines with channels for data processing
  • Fan-out/Fan-in: Distribute work across multiple goroutines
  • Worker Pool: Fixed number of workers processing from a queue
  • Select with Timeout: Prevent goroutines from blocking indefinitely

Synchronization

  • Mutex: Protect shared resources from concurrent access
  • RWMutex: Allow multiple readers or one writer
  • WaitGroup: Wait for collection of goroutines to finish
  • Once: Execute initialization code exactly once

Learning Go

Getting Started

  • • Install Go from golang.org
  • • Set up GOPATH and GOROOT (or use Go modules)
  • • Learn basic syntax and data types
  • • Practice with Go Playground (play.golang.org)

Intermediate Topics

  • • Interfaces and method sets
  • • Goroutines and channel communication
  • • Error handling patterns
  • • Package design and organization

Advanced Topics

  • • Reflection and runtime inspection
  • • Build constraints and cross-compilation
  • • Performance profiling with pprof
  • • CGO for C integration

Quick Reference Guide

Go Data Types Reference

Basic Types

TypeExampleZero ValueDescription
int420Platform-dependent integer
string"hello"""UTF-8 string
booltruefalseBoolean values
[]int[1, 2, 3]nilDynamic array
map[string]int{"a": 1}nilHash table
chan intmake(chan int)nilCommunication channel
*int&xnilPointer to int
interface{}any valuenilEmpty interface (any type)

Common Operations

Type Checking:

value, ok := x.(Type) - Type assertion

reflect.TypeOf(x) - Get type at runtime

Memory Allocation:

new(Type) - Allocate and return pointer

make([]Type, len, cap) - Create slices, maps, channels

Length and Capacity:

len(slice) - Get length of slice/map/channel

cap(slice) - Get capacity of slice/channel

Common Go Packages

Standard Library

  • fmt - Formatted I/O
  • net/http - HTTP client/server
  • encoding/json - JSON handling
  • time - Time utilities
  • os - Operating system interface

Concurrency

  • sync - Synchronization primitives
  • context - Request-scoped values
  • sync/atomic - Atomic operations
  • runtime - Go runtime functions

Testing & Debugging

  • testing - Testing framework
  • log - Logging utilities
  • errors - Error handling
  • reflect - Runtime reflection

Go CLI Commands Reference

Development

go run main.go
go build -o app
go install
go fmt ./...
go vet ./...

Testing

go test ./...
go test -v -cover
go test -bench=.
go test -race
go test -short

Modules

go mod init
go mod tidy
go get package
go mod download
go list -m all