Does anyone have any idea why method sets were designed like this?

Method sets of pointer types include the methods defined on the type
that the pointer points to (Explicitly pointed out in spec
https://go.dev/ref/spec#Method_sets)

I get the idea that having a pointer means that one can mutate the
value - so in essence it may be useful to have the pointer method set
contain the value method set.
But having a pointer to a value does not guarantee the existence of value.

Let's have a look at this trivial example: https://go.dev/play/p/ztNRPYfoAuk

type num interface {

num() int
}

type example struct{}

func (e example) num() int {
  return 42
}

func useNum(n num) {
  fmt.Println(n == nil)
  v := reflect.ValueOf(n)
  fmt.Println(v.Kind() == reflect.Ptr && v.IsNil())
  fmt.Println(n.num())
}

func main() {
  var e1 example
  var e2 *example
  useNum(e1)
  useNum(e2)
}

useNum has no safe way to call the num() method, even though we are
sure it is safe to call on a nil, in essence it never accesses the
state of the example struct.
However a caller can substitute a value with a pointer. Within the
useNum function we cannot guard with a n != nil since it receives an
interface and it will not be nil.
The only way to guard is with reflection.

This same method is also used in Go standard library:
- https://go.dev/src/fmt/print.go#L592
- https://go.dev/src/log/slog/handler.go#L564

So given this - is there any source on why method sets were designed this way?

Kind regards:
al_shopov

-- 
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 visit 
https://groups.google.com/d/msgid/golang-nuts/CAP6f5Mm1eF4XZw5sJMvrP4-sb2DkppoFuAtzbwUcbdXQyP1J8w%40mail.gmail.com.

Reply via email to