# Structs and Methods — Go (Golang)

Source: https://www.skillbyai.com/en/go/t-structs

> Value versus pointer receivers.

## Receivers decide what changes

A **struct** groups fields; **methods** attach behaviour to a type. A method with a **value receiver** `(a Account)` gets a copy, so changes do not affect the caller's value; a **pointer receiver** `(a *Account)` can modify the original and avoids copying large structs. Go calls pointer methods on addressable values automatically. Use pointer receivers when a method mutates state or the struct is large, and be consistent within a type.

## Composition over inheritance

Go models data with structs, behaviour with methods and small interfaces, and reuse with generics.

![Three ideas: structs and methods, interfaces, generics.](assets/figures/go/section-3-map.svg) — Figure 3.1 — Structs, interfaces and generics.

## A value receiver that silently changes nothing, run

I ran this with Go 1.27.1 (`go run .` in a module named demo, standard library only). BrokenDeposit modifies a copy, so the balance stays 100; Deposit uses a pointer receiver and the balance becomes 150.

```go
package main

import "fmt"

type Account struct {
	Owner   string
	Balance int
}

func (a Account) Describe() string { // value receiver: works on a copy
	return fmt.Sprintf("%s has %d", a.Owner, a.Balance)
}

func (a *Account) Deposit(n int) { // pointer receiver: modifies the original
	a.Balance += n
}

func (a Account) BrokenDeposit(n int) {
	a.Balance += n // changes only the copy
}

func main() {
	acc := Account{Owner: "Asha", Balance: 100}
	acc.BrokenDeposit(50)
	fmt.Println(acc.Describe())
	acc.Deposit(50)
	fmt.Println(acc.Describe())
}
```

Output:

```
Asha has 100
Asha has 150
```

## Mutating methods need pointer receivers

If a method should change the receiver, use a pointer receiver; a value receiver compiles fine but changes only a copy.

**Quiz:** Why did BrokenDeposit not change the balance?

- [ ] The balance field is unexported
- [ ] Go structs are immutable
- [x] It has a value receiver, so it modified a copy
- [ ] Methods cannot change fields

*Answer:* It has a value receiver, so it modified a copy. Pointer receivers modify the original.
