Go Cheatsheet

Structs

Use this Go reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Defining a Struct

type Person struct {
    Name string
    Age  int
    Email string
}

Fields starting with uppercase are exported (public); lowercase are unexported (package-private).

Creating Struct Values

// Named field literal (preferred — order-independent, robust)
p := Person{Name: "Alice", Age: 30, Email: "alice@example.com"}

// Positional literal (fragile — avoid for structs with many fields)
p := Person{"Alice", 30, "alice@example.com"}

// Zero value (all fields set to their zero)
var p Person  // Person{"", 0, ""}

// Pointer to a new struct
p := &Person{Name: "Bob", Age: 25}

// new() — returns zero-valued pointer
p := new(Person)  // equivalent to &Person{}

Accessing and Modifying Fields

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

ptr := &p
ptr.Name = "Bob"     // auto-dereferenced; same as (*ptr).Name = "Bob"

Structs Are Value Types

Assignment copies the entire struct.

a := Person{Name: "Alice"}
b := a       // b is a copy
b.Name = "Bob"
fmt.Println(a.Name)  // "Alice" — unchanged

Anonymous Structs

point := struct {
    X, Y int
}{X: 10, Y: 20}

// Common in tests or one-off table data
cases := []struct {
    input    string
    expected int
}{
    {"abc", 3},
    {"", 0},
}

Struct Tags

Metadata annotations read at runtime by packages like encoding/json, database/sql, etc.

type User struct {
    ID    int    `json:"id" db:"id"`
    Name  string `json:"name" db:"name"`
    Email string `json:"email,omitempty" db:"email"`
    Pass  string `json:"-"`                   // exclude from JSON
}

Common tag options for encoding/json: - json:"fieldname" — override key name - json:",omitempty" — omit if zero value - json:"-" — always omit - json:",string" — encode number as JSON string

Methods on Structs

type Rectangle struct {
    Width, Height float64
}

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

func (r Rectangle) Perimeter() float64 {
    return 2 * (r.Width + r.Height)
}

func (r *Rectangle) Scale(factor float64) {
    r.Width *= factor
    r.Height *= factor
}

rect := Rectangle{Width: 3, Height: 4}
rect.Area()       // 12
rect.Scale(2)     // Width=6, Height=8

Constructor Functions

Go has no constructors. Convention is a New... function.

type Server struct {
    host    string
    port    int
    timeout time.Duration
}

func NewServer(host string, port int) *Server {
    return &Server{
        host:    host,
        port:    port,
        timeout: 30 * time.Second,
    }
}

s := NewServer("localhost", 8080)

Embedding (Composition)

Go uses embedding instead of inheritance. Methods of the embedded type are promoted.

type Animal struct {
    Name string
}

func (a Animal) Speak() string {
    return a.Name + " makes a sound"
}

type Dog struct {
    Animal         // embedded (no field name)
    Breed string
}

// Dog "inherits" Speak via promotion
d := Dog{Animal: Animal{Name: "Rex"}, Breed: "Husky"}
d.Speak()       // "Rex makes a sound"
d.Name          // promoted field access
d.Animal.Name   // explicit access also works

Embedding a pointer

type Logger struct{ *log.Logger }

Overriding promoted methods

func (d Dog) Speak() string {
    return d.Name + " barks"  // shadows Animal.Speak
}
d.Speak()         // "Rex barks"
d.Animal.Speak()  // "Rex makes a sound"

Embedding an interface

Embedding an interface in a struct makes the struct satisfy that interface (useful for testing/mocking).

type ReadWriter struct {
    io.Reader
    io.Writer
}

Anonymous Fields

Fields without an explicit name — the type name becomes the field name.

type Base struct {
    ID int
}

type Derived struct {
    Base        // anonymous field; accessed as d.Base or d.ID
    Value string
}

Struct Comparison

Structs are comparable if all fields are comparable. Two struct values are equal when all fields are equal.

type Point struct{ X, Y int }
p1 := Point{1, 2}
p2 := Point{1, 2}
fmt.Println(p1 == p2)  // true

Structs containing slices, maps, or functions are not comparable with ==.

Copying Structs

original := Person{Name: "Alice", Age: 30}
copy := original           // shallow copy
pCopy := *&original        // also shallow copy via pointer dereference

// Deep copy: implement manually or use a library

Shallow copy is usually sufficient for structs of primitive fields. For slices/maps as fields, copy the contents explicitly.

Struct in JSON (encoding/json)

import "encoding/json"

type Product struct {
    ID    int     `json:"id"`
    Name  string  `json:"name"`
    Price float64 `json:"price,omitempty"`
}

// Marshal
p := Product{ID: 1, Name: "Widget", Price: 9.99}
data, err := json.Marshal(p)
// {"id":1,"name":"Widget","price":9.99}

// Unmarshal
var p2 Product
err = json.Unmarshal(data, &p2)

// Pretty-print
data, _ = json.MarshalIndent(p, "", "  ")

// Streaming
enc := json.NewEncoder(os.Stdout)
enc.Encode(p)

dec := json.NewDecoder(r)
dec.Decode(&p2)

Generics with Structs (Go 1.18+)

type Stack[T any] struct {
    items []T
}

func (s *Stack[T]) Push(v T)  { s.items = append(s.items, v) }
func (s *Stack[T]) Pop() (T, bool) {
    if len(s.items) == 0 {
        var zero T
        return zero, false
    }
    n := len(s.items) - 1
    v := s.items[n]
    s.items = s.items[:n]
    return v, true
}

s := Stack[int]{}
s.Push(1)
s.Push(2)
v, _ := s.Pop()  // 2

Gotchas

// Cannot take address of struct literal... but can with & prefix
p := &Point{1, 2}   // OK

// Unexported fields cannot be accessed outside the package
// Cannot embed a pointer to an unexported type from another package

// Nil pointer dereference
var p *Person
p.Name  // PANIC: nil pointer dereference
// Always check: if p != nil { ... }

// Struct embedding does NOT give you polymorphism —
// the promoted method set only works if the interface requires the concrete type