liveBook · Manning

Call by value

As explained in 100 Go Mistakes and How to Avoid Them

A value copy is an independent value produced by copying another value rather than referring to the original value.

A common mistake is expecting a range loop to mutate a slice of structs. Go assigns values by copying them, so the loop variable is independent of the slice element. section 4.1.2

accounts := []account{
    {balance: 100.},
    {balance: 200.},
    {balance: 300.},
}
for _, a := range accounts {
    a.balance += 1000
}

This loop increments each copied account value, leaving the original slice as [{100} {200} {300}]. section 4.1.2

To update struct elements, mutate them through their indexes. A classic for loop and an index-only range loop have the same effect; choose the latter when selectively targeting elements. section 4.1.2

for i := range accounts {                #1
    accounts[i].balance += 1000
}
 
for i := 0; i < len(accounts); i++ {     #2
    accounts[i].balance += 1000
}

Both indexed forms update the accounts stored in the slice rather than temporary copies. section 4.1.2

A pointer changes the mutation path. In a slice of account pointers, copying the pointer still lets the loop variable reach and modify the original account. section 4.1.2

accounts := []*account{       #1
    {balance: 100.},
    {balance: 200.},
    {balance: 300.},
}
for _, a := range accounts {
    a.balance += 1000         #2
}

The range variable receives a copied address, so changing a.balance changes the pointed-to account. section 4.1.2

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Explains struct and pointer copying, then stops at practical slice-update patterns rather than language-runtime internals.
Examples
Uses account balances to contrast ineffective value-variable mutation with indexed and pointer-based updates.
What it assumes
Assumes familiarity with Go range loops, slices, structs, and pointers.
What you can do after
Apply value-copy rules to choose a loop form that predictably mutates or preserves slice elements.
How it connects
Connects value copies with range loops, slices, structs, indexes, pointers, and mutation.

Also explained in

Compare how 3 books explain call by value →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.