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" — unchangedAnonymous 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}, }
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 libraryShallow 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