anatollupacescu / go-code-time

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pointers

  1. pointer receivers vs value receivers
  2. value types vs pointer types vs reference types
  3. collection of pointers vs collection of values

General guidelines for receivers:

When choosing the receiver type - "If in doubt, use a pointer" - or Dave Cheney's advice: you should prefer declaring methods on *T unless you have a strong reason to do otherwise.

The reasons for using a value receiver are to avoid getting things changed by surprise via a pointer or if it yields more readable code.

Before using a value receiver we must ask ourselves: If the method does not mutate its receiver, does it need to be a method?

Using values as function call arguments also makes sense if structs are small and likely to stay that way Point2D{x,y} as this approach is more GC friendly.

Use pointer receiver:

  1. to change the internal state of the object.
  2. when referencing to atomic types like sync.Mutex.
  3. to signal to user that this variable is not supposed to be copied: *fs.File or *testing.T
  4. you need reallocate the slice or otherwise change the underlying backing data structure.

General advices regarding pointers

  • Don't use them only to improve speed, unless there's an explicit requirement and benchmark tests.
  • Don't use pointers to basic data types unless null has semantic significance, or the pointer is required by the used library, like in the case of serialization.
  • Slices or maps of pointers is a corner case, should be only use when there's a strong case for it, like the need to change the state of the individual elements in the collection. They don't normally add any benefits but do add overhead because of increased chance of cache misses (gc pressure)
  • Because in Go every assignment is a copy - if by some requirement you must use an array (and not a slice) then as a workaround it makes sense to use an array of pointers.

Pointers as arguments:

If you pass them as arguments the expectation is still that the client will not change the state the pointer is referencing, unless it's reflected in the function name.

Bonus:

How large is large? Assume it's equivalent to passing all its elements as arguments to the method. If that feels too large, it's also too large for the receiver.

Links

  1. https://www.callicoder.com/golang-pointers/ (the basics)
  2. https://www.ardanlabs.com/blog/2014/12/using-pointers-in-go.html
  3. https://go101.org/article/pointer.html
  4. https://dave.cheney.net/2018/07/12/slices-from-the-ground-ue

Note

To run the ex9 please start a posgres container like so:

docker run --rm -e POSTGRES_USER=user -e POSTGRES_PASSWORD=pass -p 5432:5432 postgres

About


Languages

Language:Go 95.1%Language:Dockerfile 4.9%