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.
📚 Practice what you've learned with our Go Flashcards
Variables
Basic SyntaxDeclare and initialize variables in Go
Syntax:
var name type = value
name := value // short declarationExamples:
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 = valueExamples:
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 := *pExamples:
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) // bufferedExamples:
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@versionExamples:
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