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.
Variables
Basic SyntaxDeclare and initialize variables in Go
Syntax:
var name type = value
name := value // short declaration
Examples:
var name string = "John"
Explicit type declarationage := 25
Short variable declarationvar x, y int = 10, 20
Multiple variable declarationvar (
name = "Alice"
age = 30
)
Variable block declarationNotes:
Go is statically typed. Use := for new variables, = for existing ones
Constants
Basic SyntaxDeclare constants in Go
Syntax:
const NAME = value
const NAME type = value
Examples:
const Pi = 3.14159
Simple constantconst MaxUsers int = 100
Typed constantconst (
Red = "red"
Green = "green"
Blue = "blue"
)
Constant blockconst (
A = iota // 0
B // 1
C // 2
)
Using iota for enumerationNotes:
Constants are computed at compile time and cannot be changed
Functions
Basic SyntaxDefine 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 returnfunc add(a, b int) int {
return a + b
}
Function with multiple parametersfunc divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
Function with multiple return valuesfunc sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
Variadic functionNotes:
Functions are first-class citizens and can return multiple values
Structs
Basic SyntaxDefine custom types using structs
Syntax:
type Name struct {
field1 type1
field2 type2
}
Examples:
type Person struct {
Name string
Age int
}
Basic struct definitionp := Person{Name: "Alice", Age: 30}
Struct initializationtype User struct {
ID int `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
}
Struct with JSON tagsfunc (p Person) Greet() string {
return "Hello, I'm " + p.Name
}
Method on structNotes:
Structs are value types and support methods and tags for serialization
Packages
Basic SyntaxOrganize code using packages
Syntax:
package name
import "package/path"
Examples:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
Main package with importimport (
"fmt"
"os"
"time"
)
Multiple importsimport (
f "fmt"
_ "github.com/lib/pq"
)
Import alias and blank importpackage utils
// Exported function (capitalized)
func FormatName(s string) string {
return strings.Title(s)
}
// unexported function
func helper() {}
Package with exported/unexported functionsNotes:
Capitalized names are exported (public), lowercase names are private to package
Arrays & Slices
Data TypesWork 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 initializationslice := []string{"apple", "banana", "cherry"}
Slice literalnums := make([]int, 5, 10)
fmt.Println(len(nums), cap(nums)) // 5, 10
Creating slice with makeslice = append(slice, "date")
slice = append(slice, "elderberry", "fig")
Appending to slicesubSlice := slice[1:3] // elements 1 and 2
Slice operationsNotes:
Arrays have fixed size, slices are dynamic. Use slices for most cases
Maps
Data TypesUse 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 literalm := make(map[string]int)
m["key"] = 42
Creating and setting map valuesvalue, ok := m["key"]
if ok {
fmt.Println("Found:", value)
}
Checking if key existsdelete(m, "key") // Remove key-value pair
Deleting from mapfor key, value := range ages {
fmt.Printf("%s: %d\n", key, value)
}
Iterating over mapNotes:
Maps are reference types and must be initialized before use
Interfaces
Data TypesDefine interfaces for polymorphism
Syntax:
type InterfaceName interface {
Method1() returnType
Method2(param type) returnType
}
Examples:
type Writer interface {
Write([]byte) (int, error)
}
Simple interface definitiontype Shape interface {
Area() float64
Perimeter() float64
}
Interface with multiple methodsfunc (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// Rectangle implements Shape interface
Implementing interface implicitlyvar s Shape = Rectangle{Width: 10, Height: 5}
area := s.Area() // Polymorphism
Using interface for polymorphismfunc 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 TypesWork 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 usagefunc increment(x *int) {
*x++
}
num := 5
increment(&num)
fmt.Println(num) // 6
Passing pointer to functionp := new(int) // Allocates memory, returns pointer
*p = 100
Using new() to allocate memorytype Person struct {
Name string
}
p := &Person{Name: "Alice"}
Pointer to structNotes:
Go has pointers but no pointer arithmetic. Use & to get address, * to dereference
Goroutines
ConcurrencyRun functions concurrently using goroutines
Syntax:
go function()
go func() { }()
Examples:
go fmt.Println("Hello from goroutine")
Simple goroutinego func() {
fmt.Println("Anonymous goroutine")
}()
Anonymous function goroutinefor i := 0; i < 3; i++ {
go func(id int) {
fmt.Printf("Worker %d\n", id)
}(i)
}
Multiple goroutines with parametersvar wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("Work done")
}()
wg.Wait()
Using WaitGroup to wait for goroutinesNotes:
Goroutines are lightweight threads managed by Go runtime. Always ensure proper synchronization
Channels
ConcurrencyCommunicate 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 communicationch := make(chan int, 2) // Buffered channel
ch <- 1
ch <- 2
fmt.Println(<-ch, <-ch)
Buffered channelch := make(chan int)
close(ch)
val, ok := <-ch
fmt.Println(val, ok) // 0, false
Closing channels and checking statusfor val := range ch {
fmt.Println(val)
}
Ranging over channelch := make(chan<- int) // Send-only
ch2 := make(<-chan int) // Receive-only
Directional channelsNotes:
Channels enable safe communication between goroutines. Use buffered channels to avoid blocking
Select Statement
ConcurrencyHandle 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 timeoutselect {
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 defaultfor {
select {
case msg := <-ch:
process(msg)
case <-quit:
return
}
}
Select in infinite loopNotes:
Select lets goroutines wait on multiple channel operations. Default case makes it non-blocking
Mutex
ConcurrencySynchronize 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 operationsvar mu sync.RWMutex
func read() {
mu.RLock()
defer mu.RUnlock()
// Read operation
}
Read-write mutex for concurrent readsvar once sync.Once
func initialize() {
once.Do(func() {
fmt.Println("Initialized once")
})
}
Using sync.Once for one-time initializationNotes:
Always use defer to unlock mutex. RWMutex allows multiple readers or one writer
Error Handling
Error HandlingHandle 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 checkingimport "errors"
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
Creating custom errorsimport "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 typeerr := someFunction()
if err != nil {
return fmt.Errorf("failed to process: %w", err)
}
Error wrapping with fmt.ErrorfNotes:
Errors are values, not exceptions. Always check and handle errors explicitly
Panic & Recover
Error HandlingHandle 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 panicif x < 0 {
panic("x cannot be negative")
}
Using panic for unrecoverable errorsfunc 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 deferNotes:
Use panic for programmer errors, not for normal error handling. Recover only works inside deferred functions
HTTP Server
HTTP & WebCreate 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 serverfunc 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 endpointmux := http.NewServeMux()
mux.HandleFunc("/users", usersHandler)
mux.HandleFunc("/posts", postsHandler)
http.ListenAndServe(":8080", mux)
Using custom mux for routingserver := &http.Server{
Addr: ":8080",
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
}
server.ListenAndServe()
HTTP server with timeoutsNotes:
net/http package provides a complete HTTP server implementation
HTTP Client
HTTP & WebMake 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 requestdata := strings.NewReader(`{"name": "John"}`)
resp, err := http.Post("https://api.example.com/users", "application/json", data)
POST request with JSONclient := &http.Client{
Timeout: 30 * time.Second,
}
resp, err := client.Get(url)
HTTP client with timeoutreq, _ := 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 headersNotes:
Always close response body and handle timeouts for production code
JSON Handling
HTTP & WebWork 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 JSONjsonStr := `{"id": 1, "name": "Bob"}`
var user User
err := json.Unmarshal([]byte(jsonStr), &user)
Unmarshal JSON to structencoder := json.NewEncoder(w) // w is io.Writer
encoder.Encode(user)
Stream encoding to writerdecoder := json.NewDecoder(r) // r is io.Reader
var user User
err := decoder.Decode(&user)
Stream decoding from readerNotes:
Use struct tags to control JSON field names. Marshal/Unmarshal for []byte, Encode/Decode for streams
Unit Tests
TestingWrite 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 testfunc TestDivide(t *testing.T) {
_, err := Divide(10, 0)
if err == nil {
t.Error("Expected error for division by zero")
}
}
Testing error conditionsfunc 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 testsNotes:
Run tests with 'go test'. Test files must end with _test.go
Benchmarks
TestingWrite 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 benchmarkfunc 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 resetfunc 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 timingNotes:
Run benchmarks with 'go test -bench=.'. Use b.ResetTimer() to exclude setup time
Go Modules
Package ManagementManage 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 modulego get github.com/gin-gonic/gin
Add dependencygo get github.com/gin-gonic/gin@v1.9.1
Add specific versiongo mod tidy
Clean up dependenciesgo mod download
Download dependenciesgo list -m all
List all dependenciesNotes:
Go modules are the official dependency management system since Go 1.11
Go CLI Commands
Package ManagementCommon Go command line operations
Syntax:
go command [arguments]
Examples:
go run main.go
Run Go program directlygo build -o myapp main.go
Build executablego install github.com/user/tool@latest
Install Go programgo test ./...
Run all tests recursivelygo test -v -cover
Run tests with verbose output and coveragego fmt ./...
Format all Go filesgo vet ./...
Static analysis of codeNotes:
Go CLI provides comprehensive tooling for development, testing, and deployment
Gin Framework
Popular LibrariesHTTP 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 serverr.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 bindingr.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id")
c.JSON(200, gin.H{"user_id": id})
})
URL parametersr.Use(gin.Logger())
r.Use(gin.Recovery())
r.Use(corsMiddleware())
Middleware usageNotes:
Gin is a high-performance HTTP framework with minimal memory footprint
Echo Framework
Popular LibrariesMinimalist 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 servere.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 bindinge.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 Echoe.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Use(middleware.CORS())
Echo middlewareNotes:
Echo is optimized for high performance and extensibility with rich middleware ecosystem
GORM ORM
Popular LibrariesObject 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 migrationuser := User{Name: "Alice", Email: "alice@example.com"}
result := db.Create(&user)
Create recordvar user User
db.First(&user, 1) // find by primary key
db.First(&user, "name = ?", "Alice") // find by condition
Query recordsdb.Model(&user).Update("name", "Bob")
db.Model(&user).Updates(User{Name: "Bob", Age: 30})
Update recordsvar users []User
db.Where("age > ?", 18).Find(&users)
db.Order("age desc").Limit(10).Find(&users)
Advanced queriesNotes:
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
Type | Example | Zero Value | Description |
---|---|---|---|
int | 42 | 0 | Platform-dependent integer |
string | "hello" | "" | UTF-8 string |
bool | true | false | Boolean values |
[]int | [1, 2, 3] | nil | Dynamic array |
map[string]int | {"a": 1} | nil | Hash table |
chan int | make(chan int) | nil | Communication channel |
*int | &x | nil | Pointer to int |
interface{} | any value | nil | Empty interface (any type) |
Common Operations
value, ok := x.(Type) - Type assertion
reflect.TypeOf(x) - Get type at runtime
new(Type) - Allocate and return pointer
make([]Type, len, cap) - Create slices, maps, channels
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