To give a real-world example:

https://pkg.go.dev/github.com/prometheus/client_golang/prometheus

type metrics struct {
        cpuTemp    prometheus.Gauge
        hdFailures *prometheus.CounterVec
}

Question: why is prometheus.Gauge not a pointer, but *prometheus.CounterVec 
is a pointer?

Answer: because prometheus.Gauge is an interface, whereas 
prometheus.CounterVec is a struct.

An interface essentially already *contains* a pointer to a data value - in 
fact, a tuple of (type, pointer).  So you should never take a pointer to an 
interface.  Just pass the interface value, and it will copy the (type, 
pointer) pair.

However, when you extract a value from an interface, it *will* always copy 
the internal value.  This avoids aliasing issues: someone who passes an 
interface value to someone else, won't expect the recipient to be able to 
change the sender's copy.

e.g.
https://go.dev/play/p/u5y3Kwm9Ydz

Of course, if your interface *contains* a pointer, then the recipient of 
the interface can modify the thing being pointed to.
https://go.dev/play/p/o_XAJtNuyGF

But they can't modify the pointer itself held within the interface, to make 
it point to something else.

The short version is: avoid pointers to interfaces, as the FAQ says.  
Instead, let a concrete pointer value satisfy an interface.

On Friday, 25 November 2022 at 07:40:59 UTC Nigel Tao wrote:

> Possibly relevant:
> https://go.dev/doc/faq#pointer_to_interface
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/a13cea55-ea38-45c7-b513-8f1b1addc993n%40googlegroups.com.

Reply via email to