Method
Go does not have classes. However, you can define methods on types.
A method is a function with a special receiver argument.
The receiver appears in its own argument list between the func
keyword and the method name.
Method on struct types
In this example, the Abs
method has a receiver of type Vertex
named v
.
Methods are functions
Remember: a method is just a function with a receiver argument.
Here's Abs
written as a regular function with no change in functionality.
Method on non-struct types
In this example we see a numeric type MyFloat
with an Abs
method.
You can only declare a method with a receiver whose type is defined in the same package as the method. You cannot declare a method with a receiver whose type is defined in another package (which includes the built-in types such as int
).
Pointer receivers
You can declare methods with pointer receivers.
This means the receiver type has the literal syntax *T
for some type T
. (Also, T
cannot itself be a pointer such as *int
.)
For example, the Scale
method here is defined on *Vertex
.
Methods with pointer receivers can modify the value to which the receiver points (as Scale
does here). Since methods often need to modify their receiver, pointer receivers are more common than value receivers.
Try removing the *
from the declaration of the Scale
function on line 16 and observe how the program's behavior changes.
With a value receiver, the Scale
method operates on a copy of the original Vertex
value. (This is the same behavior as for any other function argument.) The Scale
method must have a pointer receiver to change the Vertex
value declared in the main
function.
Pointers and functions
Here we see the Abs
and Scale
methods rewritten as functions.
Comparing the previous two programs, you might notice that functions with a pointer argument must take a pointer:
while methods with pointer receivers take either a value or a pointer as the receiver when they are called:
For the statement v.Scale(5)
, even though v
is a value and not a pointer, the method with the pointer receiver is called automatically. That is, as a convenience, Go interprets the statement v.Scale(5)
as (&v).Scale(5)
since the Scale
method has a pointer receiver.
The equivalent thing happens in the reverse direction.
Functions that take a value argument must take a value of that specific type:
while methods with value receivers take either a value or a pointer as the receiver when they are called: