appendix-e

Appendix E. Passing by value or by reference

 

This appendix covers

  • Understanding what “passing by value” means
  • Understanding what “passing by reference” means
  • Two special cases: maps and slices
  • A few recommendations to help make a choice

We constantly use functions in our code. These functions, most of the time, have parameters. Let’s imagine we are writing code for the bowling alley that opened last week. We need to print the scores on the screen after a player has had their shots. We write this function :

Listing E.1 Showing a player’s score
type Player struct {                        
    name  string                        
    score int                        
}                                
 
// ShowScore displays the player’s score                
func ShowScore(p Player) {                    
    fmt.Printf("Player %q has %d points!\n", p.name, p.score)    
}                                

This does the job, we’re happy. However, we notice that the function updating the score doesn’t seem to work.

Listing E.2 Updating the player’s score
func AddPoints(p Player, points int) {                
    p.score += points                        
}                                

Indeed, after writing a simple test, we realise that the player’s score after calling AddPoints didn’t change! The main reason behind this lies with Go’s handling of parameters in functions. The main concept here is known as passing parameters by value and passing parameters by reference.

E.1 Go passes everything by value

E.1.1 Copying parameters on the stack

E.1.2 Using pointers

E.1.3 Shallow copies

E.1.4 Functions vs methods

E.2 Special types of parameters: slices, maps, and channels

E.2.1 Passing a slice as a parameter

E.2.2 Maps, channels, …

E.3 A few recommendations

E.3.1 Passing by value should be the default

E.3.2 Passing by pointer is a minor optimisation

E.3.3 Passing by pointer when mutating

E.3.4 Using slices and maps

E.3.5 Passing a pointer to a slice or to a map

E.3.6 Writing your own Copy function