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


