Pointers are perhaps the least approachable subject related to software development. I posit that it’s due to poor examples written by advanced engineers who’ve forgotten what it’s like for devs with less understanding. Here’s my stab at explaining them.

Exotic Cars & Timeshares


Consider the following scenario.

Quinton is a member of Gotham Dream Cars’ Dream Share program. He “owns” a Lamborghini LP640 Roadsterat least part of one. Angelina is also a member and “owns” the same Lamborghini LP640 Roadster. They both “own” several other exotic cars through Dream Share.

All of Quinton’s & Angelina’s vehicles are kept in individual garages specifically tailored for storing exotic cars.

Expressing it with Code… specifically Golang

First we’ll make some statements about our exotic car scenario in English. Then we’ll then express the same statements with Go.

A blueprint exists for building exotic cars.

type Car struct {
  name string
  driver string
  miles int

A brand new Lamborghini has been constructed.

lamborghini := Car{name: "Lamborghini", miles: 0} // => {Lamborghini  0}

We’ve discovered which garage the Lamborghini is stored in.

address := &lamborghini // => 0x2101aa180

The ability to drive & park exists.

// accepts a pointer (or address) to a Car
func drive(car *Car, driver string, miles int) {
  car.driver = driver
  car.miles += miles

// accepts a pointer (or address) to a Car
func park(car *Car) {
  car.driver = ""

Quinton can drive “his” Lamborghini 100 miles then park it.

drive(&lamborghini, "Quinton", 100) // => {Lamborghini Quinton 100}
park(&lamborghini) // => {Lamborghini  100}

Angelina can drive “her” Lamborghini 100 miles then park it.

drive(&lamborghini, "Angelina", 100) // => {Lamborghini Angelina 200}
park(&lamborghini) // => {Lamborghini  200}

Dream Share can replace the Lamborghini with a new one.

*address = Car{name: "Lamborghini", miles: 0} // => {Lamborghini  0}
fmt.Println(lamborghini) // => {Lamborghini  0}

Wait… What?

If you didn’t quite grok the example above, perhaps a visualization will help.


When working with a variable we can directly manipulate the value.

Methods are different. They receive a copy of the value unless they are defined to accept a pointer (or address) to the original value.

The drive & park methods above both accept a pointer. This allows them to manipulate the original lamborghini value.

Also note that it’s possible to replace the entire value (change the memory used to hold the value) at a particular address as we did in the last example.

I’m not convinced my attempt to explain pointers improves on the existing docs, but hopefully it helps.

comments powered by Disqus