Receiver Parameter in Go
In Go, a receiver parameter is a special parameter in a method declaration that allows a type to define methods that can be called on its instances.
func (r ReceiverType) MethodName(arguments) {
// method implementation
}
The ReceiverType
is the type on which the method is defined, and it can be either a value or a pointer type. The MethodName
is the name of the method, and it can be any valid identifier.
When a method is called on a value of the ReceiverType
, Go automatically passes a copy of the value as the receiver parameter to the method. If the receiver parameter is a pointer type, Go passes a copy of the pointer, which points to the original value.
Receiver parameters allow types to define behavior that is specific to their instances, and they provide a way to encapsulate the implementation of methods within the type definition.
Example 1: A receiver parameter on a value type
type MyInt int
func (m MyInt) IsPositive() bool {
return m > 0
}
func main() {
var i MyInt = 5
fmt.Println(i.IsPositive()) // Output: true
}
In this example, we define a type MyInt
which is a value type that is an alias for the int
type.
We then define a method IsPositive
on the MyInt
type, which returns a boolean indicating whether the value is positive or not.
The method takes a receiver parameter m
of type MyInt
, which is the instance of the type that the method is called on.
In the main
function, we create an instance of MyInt
and call the IsPositive
method on it.
Example 2: A receiver parameter on a pointer type
type Person struct {
Name string
Age int
}
func (p *Person) IsAdult() bool {
return p.Age >= 18
}
func main() {
person := &Person{Name: "Alice", Age: 25}
fmt.Println(person.IsAdult()) // Output: true
}
In this example, we define a Person
struct with two fields Name
and Age
. We then define a method IsAdult
on the Person
type, which returns a boolean indicating whether the person is an adult or not. The method takes a receiver parameter p
of type *Person
, which is a pointer to the instance of the type that the method is called on. In the main
function, we create a pointer to a Person
and call the IsAdult
method on it.
How it is differnt than normal method parameter
let’s understand the difference using an example
type Rectangle struct {
width, height float64
}
// A method with a receiver parameter
func (r Rectangle) Area() float64 {
return r.width * r.height
}
// A method with a regular method parameter
func Perimeter(width, height float64) float64 {
return 2 * (width + height)
}
func main() {
rect := Rectangle{width: 10, height: 5}
// Calling a method with a receiver parameter
area := rect.Area()
// Calling a method with regular method parameters
perimeter := Perimeter(rect.width, rect.height)
}
we define a Rectangle
struct and two methods: Area
and Perimeter
.
The Area
method is defined with a receiver parameter r
of type Rectangle
, and it calculates the area of the rectangle.
The Perimeter
method is defined with two regular method parameters width
and height
, and it calculates the perimeter of a rectangle given its width and height.
In the main
function, we create an instance of Rectangle
and call both methods on it.
When we call the Area
method, the Rectangle
instance is automatically passed as the receiver parameter r
to the method.
When we call the Perimeter
method, we pass the width
and height
values of the Rectangle
instance as regular method parameters.