Go

Structs & Methods

A Go struct starts out looking identical to a C struct — a bundle of named fields. What's different is what you can attach to it: methods, functions associated with a specific type, giving Go something close to C++'s classes — deliberately without inheritance, Go's most consequential design decision covered in this chapter.

Quick reference
What it is
A struct is a bundle of named fields, like C's. A method is a function with a special "receiver" parameter, associating it with a specific type.
Mental model
Where C++ says "a class owns its methods," Go says "a method is just a function that happens to take a specific type as its first, special argument" — syntactically attached, conceptually separate.
Key numbers
Two receiver kinds: value receivers (get a copy) and pointer receivers (can modify the original) — choosing between them is this chapter's most important practical decision.
Reach for it when
Bundling related data (a struct) is needed almost everywhere; methods specifically when behavior naturally belongs to that data.

Structs

type SensorReading struct {
    Timestamp int
    Value     float64
    Status    string
}

r := SensorReading{Timestamp: 1000, Value: 23.5, Status: "OK"}
fmt.Println(r.Timestamp)   // 1000 — dot operator, exactly like C

Field names starting with a capital letter (Timestamp, not timestamp) are exported — visible outside the package that defines them. This is Go's entire access control mechanism: capitalization, not a public/private keyword like C++'s.

Methods and receivers

type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {   // (c Circle) is the RECEIVER — associates Area with Circle
    return 3.14159 * c.Radius * c.Radius
}

circle := Circle{Radius: 5}
fmt.Println(circle.Area())   // 78.5397 — called just like a C++ method

(c Circle) between func and the method name is the receiver — it's what makes Area callable as circle.Area() instead of a free-floating function. Structurally, this is the same "hidden first argument" idea from C++'s member functions, just written explicitly instead of implicitly.

Value receivers vs. pointer receivers

func (c Circle) Scale(factor float64) {   // VALUE receiver — gets a COPY
    c.Radius *= factor                     // only changes the copy — caller's circle is unaffected
}

func (c *Circle) ScalePtr(factor float64) {   // POINTER receiver — gets the REAL thing
    c.Radius *= factor                          // actually changes the caller's circle
}

circle := Circle{Radius: 5}
circle.Scale(2)
fmt.Println(circle.Radius)      // still 5 — Scale only touched a copy

circle.ScalePtr(2)
fmt.Println(circle.Radius)      // 10 — ScalePtr touched the real thing

This is exactly the pass-by-value vs. pass-by-reference distinction from C, applied to methods specifically. The practical rule of thumb: use a pointer receiver whenever a method needs to modify the receiver, or when the struct is large enough that copying it on every call would be wasteful.

Embedding — composition instead of inheritance

Go has no inheritance at all — deliberately, a core design decision, not a missing feature. Instead, a struct can embed another struct, gaining its fields and methods directly:

type Sensor struct {
    Name string
}

func (s Sensor) PrintName() {
    fmt.Println(s.Name)
}

type TemperatureSensor struct {
    Sensor              // embedded — NOT "extends Sensor," just "contains a Sensor, promoted"
    Unit string
}

t := TemperatureSensor{Sensor: Sensor{Name: "Temp"}, Unit: "Celsius"}
t.PrintName()          // works — Sensor's method is "promoted" up to TemperatureSensor
fmt.Println(t.Name)     // works — Sensor's field is promoted too

This looks similar to C++ inheritance at the call site, but it's genuinely different underneath: TemperatureSensor literally contains a Sensor value as a field — there's no shared type hierarchy, no virtual, and no "is-a" relationship the compiler enforces. It's composition, with Go's syntax making the common case of "just forward these calls" nearly invisible.

Real-world applications

Gotchas

Field notes