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.