Go Fundamentals

Lesson 5 of 8

Structs and Methods

Go has no classes, but combines structs with methods (functions attached to a type) to get most of the same benefits, more explicitly.

type Student struct {
    Name string
    XP   int
}

func (s *Student) GainXP(amount int) {
    s.XP += amount
}

func (s Student) Greeting() string {
    return "Hi, I'm " + s.Name
}
ada := Student{Name: "Ada", XP: 0}
ada.GainXP(50)
fmt.Println(ada.XP)         // 50
fmt.Println(ada.Greeting()) // "Hi, I'm Ada"

func (s *Student) GainXP(...) is a method with s as its receiver, this is what attaches the function to the Student type, letting you call it as ada.GainXP(...) instead of GainXP(ada, ...).

Pointer vs. value receivers

This is the one detail that trips everyone up at first: GainXP uses a pointer receiver (*Student) because it needs to modify the struct, Greeting uses a value receiver (Student) because it only reads from it. A value receiver operates on a copy, changes inside it never affect the original:

func (s Student) BrokenGainXP(amount int) {
    s.XP += amount // only modifies the local copy, caller sees no change
}

Rule of thumb: if a method needs to modify the struct, use a pointer receiver, if it only reads, either works, but staying consistent within a type is idiomatic Go.

📝 Structs and Methods Quiz

Passing score: 70%
  1. 1.Why does GainXP use a pointer receiver (*Student) instead of a value receiver?

  2. 2.A method with a value receiver operates on a copy of the struct, so changes inside it are not visible to the caller.

  3. 3.In "func (s *Student) GainXP(...)", s is called the method's ____.