3

Let's say I have a struct

type Rectangle struct {
    length, width int
}

and I want to add a method to it:

func (r Rectangle) Area() int {
    return r.length * r.width
}

Why must I give it a variable name here r?

icza
  • 389,944
  • 63
  • 907
  • 827
anonrose
  • 1,271
  • 3
  • 12
  • 19

2 Answers2

9

Because there is no implicit identifier denoting the actual receiver value (like this in Java), and if you want to refer to the fields or methods of the receiver value (Rectangle value), you need an identifier that you can use.

Note that the spec does not require you to name the receiver value, e.g. the following using the blank identifier is a valid syntax:

func (_ Rectangle) Foo() string {
    return "foo"
}

Or even this: omitting the receiver name (the parameter name):

func (Rectangle) Foo() string {
    return "foo"
}

Relevant section from the spec: Method declarations:

MethodDecl   = "func" Receiver MethodName ( Function | Signature ) .
Receiver     = Parameters .

Where Parameters is:

Parameters     = "(" [ ParameterList [ "," ] ] ")" .
ParameterList  = ParameterDecl { "," ParameterDecl } .
ParameterDecl  = [ IdentifierList ] [ "..." ] Type .

As you can see in the last line, the IdentifierList is optional (but Type is required).

icza
  • 389,944
  • 63
  • 907
  • 827
1

Struct methods are like Class methods. The variable 'r' is a reference to the struct/class instance/object that the method is being applied to. Without that reference, you will not be able to access whatever is contained within that struct/object.

Lets say for example, I created smallRectangle using your struct:

var smallRectangle = Rectangle{5,3}

Now I want to calculate the area using the Rectangle method Area

area := smallRectangle.Area()

Lets look at what happens within the function. r from the method declaration becomes a copy of smallRectangle since that's the struct object calling it.

func (smallRectangle Rectangle) Area() int {
    return smallRectangle.length * smallRectangle.width
}

As indicated by Icza, there is no implicit identifier like self or this, so the only way for the method to access the values of the struct is through the identifier r.

Anfernee
  • 1,445
  • 1
  • 15
  • 26