Go Cheat Sheet

Hello World / Program Structure

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

Main function is the program entry point. All Go programs start here.

Packages and Imports

import (
    "fmt"
    "math"
)

Import standard or custom packages. Group multiple imports in parentheses.

Variables and Constants

var name string = "Go"
const Pi = 3.14

Use var for variables, const for constants.

Data Types

var i int = 42
var f float64 = 3.14
var s string = "text"
var b bool = true

Go has strong static typing. Basic types include int, float64, string, bool.

Type Inference

x := 100
text := "Go!"

:= infers the type at compile time.

Operators

+, -, *, /, % // Arithmetic
==, !=, <, >, <=, >= // Comparison
&&, ||, ! // Logical

Go supports standard arithmetic, comparison, and logical operators.

Control Flow

if / else

if x > 0 {
    fmt.Println("Positive")
} else {
    fmt.Println("Non-positive")
}

switch

switch day {
case "Mon": fmt.Println("Start")
case "Fri": fmt.Println("Weekend")
default: fmt.Println("Midweek")
}

for Loop

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

break / continue / goto

for i := 0; i < 10; i++ {
    if i == 3 {
        continue
    }
    if i == 8 {
        break
    }
    fmt.Println(i)
}

Functions

Function Declaration

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

Multiple Return Values

func swap(a, b string) (string, string) {
    return b, a
}

Named Return Values

func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}

Variadic Functions

func sum(nums ...int) int {
    total := 0
    for _, num := range nums {
        total += num
    }
    return total
}

Closures / Anonymous Functions

func() {
    fmt.Println("Hello from anonymous function")
}()

Defer Statement

defer fmt.Println("executed last")
fmt.Println("executed first")

Panic and Recover

defer func() {
    if r := recover(); r != nil {
        fmt.Println("Recovered from", r)
    }
}()
panic("something bad happened")

Data Structures

Arrays

var arr [3]int = [3]int{1, 2, 3}

Slices

nums := []int{1, 2, 3}
nums = append(nums, 4)
copied := make([]int, len(nums))
copy(copied, nums)

Maps

m := make(map[string]int)
m["a"] = 1
fmt.Println(m["a"])

Structs

type Person struct {
    Name string
    Age  int
}
p := Person{"Alice", 30}

Pointers

x := 10
p := &x
*p = 20

Strings and UTF-8

s := "hello"
for i, r := range s {
    fmt.Printf("%d: %c
", i, r)
}

Advanced Types

Interfaces

type Speaker interface {
    Speak() string
}

type Dog struct{}

func (d Dog) Speak() string {
    return "Woof!"
}

Embedding

type Animal struct {
    Name string
}

type Dog struct {
    Animal
    Breed string
}

Embedding allows inheritance-like behavior in Go.

Type Assertions

var i interface{} = "hello"
s := i.(string)

Type assertions extract the concrete value from an interface.

Type Switches

switch v := i.(type) {
case int:
    fmt.Println("int")
case string:
    fmt.Println("string")
}

Custom Types and Aliases

type Age int

func (a Age) IsAdult() bool {
    return a >= 18
}

type MyInt = int

type creates a new type. Use = for aliases.

Concurrency

Goroutines

go func() {
    fmt.Println("Running in a goroutine")
}()

Channels

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

Buffered Channels

ch := make(chan int, 2)
ch <- 1
ch <- 2

Directional Channels

func send(ch chan<- int) {
    ch <- 1
}

func receive(ch <-chan int) int {
    return <-ch
}

select Statement

select {
case msg := <-ch:
    fmt.Println(msg)
default:
    fmt.Println("No message")
}

sync Package

var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    fmt.Println("Task")
}()
wg.Wait()
var mu sync.Mutex
mu.Lock()
x++
mu.Unlock()

Packages and Modules

Creating and Using Packages

// greet/greet.go
package greet

func Hello(name string) string {
    return "Hello, " + name
}
// main.go
package main

import (
    "fmt"
    "yourmodule/greet"
)

func main() {
    fmt.Println(greet.Hello("Go"))
}

Module System (go mod)

go mod init yourmodule

Initializes a new module in the current directory.

go mod tidy

Adds missing and removes unused modules.

Standard Library Highlights

  • fmt: Formatting and printing
  • os: File system and process
  • io, bufio: I/O operations and buffered I/O
  • strings: String manipulation
  • strconv: Conversions between strings and basic types

Error Handling

Error Type and Idioms

import "errors"

err := errors.New("something went wrong")
if err != nil {
    fmt.Println(err)
}

Custom Errors

type MyError struct {
    Msg string
}

func (e MyError) Error() string {
    return e.Msg
}

Wrapping Errors

import (
    "errors"
    "fmt"
)

wrapped := fmt.Errorf("wrap: %w", err)
if errors.Is(wrapped, err) {
    fmt.Println("matched")
}

I/O and File Handling

Reading Files

content, err := os.ReadFile("file.txt")
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(content))

Writing Files

err := os.WriteFile("output.txt", []byte("data"), 0644)

Command Line Arguments

import "os"

func main() {
    args := os.Args
    fmt.Println(args)
}

Working with JSON

import "encoding/json"

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

data := Person{"Alice", 30}
jsonData, _ := json.Marshal(data)
fmt.Println(string(jsonData))

Testing

Basic Test

import "testing"

func TestAdd(t *testing.T) {
    got := Add(2, 3)
    want := 5
    if got != want {
        t.Errorf("got %d, want %d", got, want)
    }
}

Benchmarking

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

Table-Driven Tests

var tests = []struct {
    a, b, want int
}{
    {1, 2, 3},
    {2, 2, 4},
}

func TestAddTable(t *testing.T) {
    for _, tt := range tests {
        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)
        }
    }
}

Tooling and Best Practices

Formatting and Linting

go fmt ./...
go vet ./...

Build, Run, Install, Test

go build
./program

go run main.go
go install

go test ./...

Documentation

godoc -http=:6060

Launch local documentation server.

Dependency Management

go mod tidy
go get example.com/pkg

Miscellaneous

init() Function

func init() {
    fmt.Println("Initializing...")
}

Blank Identifier

_, err := someFunc()
if err != nil {
    log.Fatal(err)
}

Shadowing and Scoping

x := 5
if true {
    x := 10 // shadows outer x
    fmt.Println(x) // 10
}
fmt.Println(x) // 5

Memory Management

Go has garbage collection. No need for manual memory allocation or deallocation.