Methods in Go
In this tutorial, we are going to discuss methods in the Go language. Go methods are similar to the Go function with one difference, i.e., the method contains a receiver argument in it. With the help of the receiver argument, the method can access the properties of the receiver.
The receiver argument has a name and a type. It appears between the func keyword and the method name.
func (receiver Type) MethodName(parameterList) (returnTypes) { }
The receiver can be of struct type or non-struct type. When you create a method in your code, the receiver and receiver type must be present in the same package.
So basically, when you attach a function to a type, that function becomes a method for that type. The method will have access to the receiver’s properties and can call the receiver’s other methods.
You cannot create a method in which the receiver type is already defined in another package, including inbuilt type like int, string, etc. If you try to do so, then the compiler will give an error.
package main
import (
"fmt"
)
type Employee struct {
name string
age int
salary int
}
func (e Employee) displayDetails() {
fmt.Println("Name : ", e.name)
fmt.Println("Salary : ", e.salary)
fmt.Println("Age : ", e.age)
}
func main() {
emp := Employee{
name: "Ashok Kumar",
salary: 50000,
age: 29,
}
emp.displayDetails()
}
Output
Name : Ashok Kumar
Salary : 50000
Age : 29
In Go language, you can create a method with a non-struct type receiver as long as the type and the method definitions are present in the same package.
If they are present in different packages like int, string, etc., the compiler will give an error because they are defined in different packages.
package main
import "fmt"
type data int
func (d1 data) multiply(d2 data) data {
return d1 * d2
}
/*
// if you try to run this code, then compiler will throw an error
func (d1 int) multiply(d2 int) int {
return d1 * d2
}
*/
func main() {
value1 := data(10)
value2 := data(20)
res := value1.multiply(value2)
fmt.Println("Final result : ", res)
}
Output
Final result : 200
Methods vs Functions
The above struct type program can be rewritten using only functions and without methods.
package main
import (
"fmt"
)
type Employee struct {
name string
age int
salary int
}
/*
displayDetails() method converted to function with Employee as parameter
*/
func displayDetails(e Employee) {
fmt.Println("Name : ", e.name)
fmt.Println("Salary : ", e.salary)
fmt.Println("Age : ", e.age)
}
func main() {
emp := Employee{
name: "Ashok Kumar",
salary: 50000,
age: 29,
}
displayDetails(emp)
}
Output
Name : Ashok Kumar
Salary : 50000
Age : 29
In the program above, the displayDetails method is converted to a function, and the Employee struct is passed as a parameter to it. This program also produces the exact same output.
So why do we have methods when we can write the same program using functions. There are a couple of reasons for this. Let’s look at them one by one.
1. Go is not a pure object-oriented programming language, and it does not support classes. Methods help you write object-oriented style code in Go. Method calls are much easier to read and understand than function calls.
2. Methods with the same name can be defined on different types, whereas functions with the same names are not allowed. Let’s assume that we have a Square and Circle structure. It’s possible to define a method named Area on both Square and Circle. This is done in the program below.
package main
import (
"fmt"
"math"
)
type Rectangle struct {
length int
width int
}
type Circle struct {
radius float64
}
func (r Rectangle) Area() int {
return r.length * r.width
}
func (c Circle) Area() float64 {
return math.Pi * c.radius * c.radius
}
func main() {
r := Rectangle{
length: 10,
width: 5,
}
fmt.Println("Area of rectangle : ", r.Area())
c := Circle{
radius: 12,
}
fmt.Println("Area of circle : ", c.Area())
}
Output
Area of rectangle : 50
Area of circle : 452.3893421169302
Difference Between Method and Function
Methods with Pointer receivers
All the examples that we saw in the previous sections had a value receiver.
With a value receiver, the method operates on a copy of the value passed to it. Therefore, any modifications done to the receiver inside the method is not visible to the caller.
// Method with pointer receiver
func (receiver *Type) MethodName(parameterList) (returnTypes) {
}
Methods with pointer receivers can modify the value to which the receiver points. Such modifications are visible to the caller of the method as well.
package main
import (
"fmt"
)
type Employee struct {
name string
age int
}
func (e Employee) changeName(newName string) {
e.name = newName
}
func (e *Employee) changeAge(newAge int) {
e.age = newAge
}
func main() {
e := Employee{
name: "Ashok Kumar",
age: 28,
}
fmt.Println("Employee name before change : ", e.name)
e.changeName("Ashok")
fmt.Println("Employee name after change : ", e.name)
fmt.Println("Employee age before change : ", e.age)
e.changeAge(29)
fmt.Println("Employee age after change : ", e.age)
}
Output
Employee name before change : Ashok Kumar
Employee name after change : Ashok Kumar
Employee age before change : 28
Employee age after change : 29
Method definition restrictions
Note that, to define a method on a receiver, we must define the receiver type in the same package.
Go doesn’t allow you to define a method on a receiver type defined in some other package (this includes built-in types such as int as well).
In all the previous examples, we define the structs and the methods in the same package main. Therefore, they worked. However, the compiler will complain if you try to define a method on a type defined in some other package.
Exported Method
Go doesn’t have any public, private or protected keyword. The only mechanism to control the visibility outside the package is using the capitalized and non-capitalized formats
- Capitalized Identifiers are exported. The capital letter indicates that this is an exported identifier and is available outside the package.
- Non-capitalized identifiers are not exported. The lowercase indicates that the identifier is not exported and will only be accessed within the same package.
That’s all about the Methods in Go language. If you have any queries or feedback, please write us email at contact@waytoeasylearn.com. Enjoy learning, Enjoy Go language.!!