On Tue, Jun 10, 2025 at 2:06 PM Alexander Shopov <a...@kambanaria.org> wrote:
>
> 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.

The method set of a type T contains the methods that are declared using T.
The method set of a type *T contains the methods that are declared
using T and the methods that are declared using *T.
This guarantees that an interface containing a value of type T does
not implement the methods that work on *T, because the value contained
in the interface is not addressable.

The fact that an interface may contain a nil value and thus may pass a
nill check but panic with a nil ptr error is one of the annoying
idiosyncrasies of Go interfaces. Method sets are not related to this.

> 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.

-- 
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/CAMV2RqqauBmu2zPNX96HZ8D1Ashm4Oip92tcijK8TZO4vF0MSg%40mail.gmail.com.

Reply via email to