Can T has method of *T?

The method World belong to *X , but I can call it on an X instance , is this by design? So what’s the relationship of the method sets of T and *T. Are they exactly the same? Many thanks.

type X struct {}
func (x X) Hello() {
}
func (x *X) World() {
}

func main() {
  a := X{}
  a.World()
}

Yes, it is by design; here it is in the language spec: The Go Programming Language Specification - go.dev.

It seems that the meaning of this paragraph is : the method set of *T contains the method set of T. But in my example , I’m calling a method of *X on an X instance. This should fail : World is not a method of X.

The short explanation is that the compiler automatically converts a.World() to (&a).World(). Per the spec a bit further down in Calls:

A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m():

Here’s an issue on StackOverflow with an excellent point about the subtle differences between the two and why you might choose one over the other:

A method which has a pointer as the receiver has the ability to modify the values of that receiver, while a method which has a value as the receiver cannot.

There’s a lot of great information in that issue. I would also use care when dealing with things that use reflection, such as MarhsalJSON. In that case it does matter which receiver you use.

Oops, I see what you mean. I mixed it up! It looks like Dean’s answer addresses your question, though!

Thank you. Got it: with this design , we have 2 kind of method : by value and by reference. Great!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.