Golang Methods Tutorial [Practical Examples]


GO

Reviewer: Deepak Prasad

Introduction to Golang Methods

Go methods are basically functions with receiver arguments between the func keyword and the name of the method. The receiver does appear in its own argument list. Go uses receivers to implement object orientation just like other languages do like python and Java where classes are used to achieve object orientation. Go does not have classes, but you can define methods on different types like struct, and non-struct types.

In Go and many other programming languages , methods are used to expose and hide properties of a type, and therefore with the help of receiver arguments , methods are used to hide and access the properties of a type.

 

Methods syntax

The unique thing about the above syntax is that the receiver type  appears in its argument list. The receiver type declares the type the function is going to be attached to. One important thing to note is that the method and the receiver have to be in the same package. This means that Go does not allow us to declare a method and receiver whose type is defined in another package and this rule applies to built in types such as int and string.

func (receiverName receiverType) methodName (parameter List)(returnTypes){
 <em>  method body</em>
}

The following figure highlights the different parts involved in defining a method. It shows the quart method attached to the type gallon based receiver via the g gallon receiver parameter:

Golang Methods Tutorial [Practical Examples]

 

Using Method with struct type receivers

In Go, you can define a method whose receiver is a struct or a non-struct type. For most of the examples in this article, structs will be used to demonstrate methods in Go. If you haven't already, install Go runtime, and create a working directory and add main.go file in your working directory to start writing Go methods.

Example

package main
 
import "fmt"
 
type User struct {
   Name  string
   Email string
}
 
func (u User) userDetails() string {
   return fmt.Sprintf("User name is :%s and email is: %s", u.Name, u.Email)
}
 
func main() {
   user1 := User{Name: "John Doe", Email: "johndoe@golinuxcloud.com"}
   fmt.Println(user1.userDetails())
}

Explanation

In the preceding example, we have created a User struct, with Name and Email attributes. We then define a method called userDetails() , with the User struct as the receiver indicated by (u User) . In the userDetails() method, we now have access to the receiver via the u receiver name. We use the dot notation to access the receiver attributes and methods like so u.Name or u.Email. In the main function, we create an instance of the User struct, and print the details of the user on the screen by calling the userDetails() method on the user1 instance.

Output

$ go run main.go
User name is :John Doe and email is: johndoe@golinuxcloud.com

 

Using Methods with non-struct receivers

In the preceding example, we defined methods with struct types. It is possible to define methods with other types that are not struct types. One important thing to note though is that when defining a method on a type, the definition of the receiver type and of the method should be in the same package.

Example

package main
 
import "fmt"
 
type myNumber int
 
func (num myNumber) square() myNumber {
   if num == 0 {
       return 1
   }
   return num * num
}
 
func main() {
   num := myNumber(25)
   sq := num.square()
   fmt.Printf("The square of %d is %d \n", num, sq)
}

Output

$ go run main.go
The square of 25 is 625

 

Using Methods with interface types

An interface in Go is a type with a defined method signature. Types with these methods defined in the interface  implement the interface implicitly. With interfaces, the methods are defined both in the interface and the receiver as shown below.

Example

package main
 
import "fmt"
 
var URL string
 
type Protocal interface {
   request(URLEndpoint string)
   response() string
}
type HTTPProtocol struct {
   URL string
}
 
func (HTTP *HTTPProtocol) request(URLEndpoint string) {
   URL = fmt.Sprintf("%s/%s", HTTP.URL, URLEndpoint)
   HTTP.URL = URL
}
func (http HTTPProtocol) response() string {
   return URL
}
func main() {
   HTTPP := HTTPProtocol{URL: "https://www.golinuxcloud.com"}
   HTTPP.request("go-methods")
   res := HTTPP.response()
   fmt.Println(res)
   fmt.Println(HTTPP)
}

Explanation

In this example, we are trying to mimic request response client server architecture. We first declare a URL string type at the top.Then we define a Protocol interface with two methods namely request()and response() . At this point, if we have a type with these methods defined, that type will implement our Protocol interface implicitly. Then we define a HTTPProtocol struct type with request()  and response() methods. The request() method has a pointer receiver, and that allows us to modify the URL attribute of the HTTPProtocol struct. We also assign the URL string type variable to the new URL. In the main function, we create an instance of the HTTPProtocol struct (HTTPP) with a URL string. We then use the request() method to pass the URL endpoint(“go-methods”), which goes ahead to effect the changes both on the URL variable and the URL attribute of the HTTPProtocol instance.

Output

$ go run main.go
https://www.golinuxcloud.com/methods
{https://www.golinuxcloud.com/methods}

 

Using Methods with value and pointer receivers

Go methods can accept both value and pointer receivers. In our previous example we used value receivers, in this section , we will work with both. A pointer in Go is a variable used to store the memory address of another variable, in this case we will use a pointer as a receiver. Go always passes by value , which means it creates a copy of the value in the function. If you call a method with a value receiver, and the method modifies that value, the caller will not see that modification made to the value. If you want to modify the value, the receiver has to be a pointer. In simple terms, we use pointer receivers in methods to modify the value the receiver points to and to avoid copying the value on each method call.

Learn more about pointers: Go Pointers Explained for Beginners [Practical Examples].

Example

package main
 
import "fmt"
 
type User struct {
   Name  string
   Email string
}
 
func (u User) userDetails() string {
   return fmt.Sprintf("User name is :%s and email is: %s", u.Name, u.Email)
}
 
func (u *User) changeDetails(newName, newEmail string) {
   u.Name = newName
   u.Email = newEmail
}
 
func main() {
   user1 := User{Name: "John Doe", Email: "johndoe@golinuxcloud.com"}
   fmt.Println(user1.userDetails())
   user1.changeDetails("Mary Doe", "marydoe@golinuxcloud.com")
   fmt.Println(user1.userDetails())
}

 

Explanation

In the above example, we add a new method called changeDetails() with a pointer receiver to the User struct type and a newName of type string in the parameter list. We then use the dot notation to get access to the receiver’s name and email attribute and change it to the newName and newEmailstring respectively. In the main function, we instantiate a new user(user1) with a name and an email. We then call the changeDetails() function on the user1 instance , which modifies the name and email to whatever name and email we pass to the changeDetails() method. When this code is executed, we notice that the name and email of the user1 changes to a new name and email courtesy of the changeDetails() method.

Output

$ go run main.go
User name is :John Doe and email is: johndoe@golinuxcloud.com
User name is :Mary Doe and email is: marydoe@golinuxcloud.com

 

Summary

In this tutorial,  we have learned about what methods are and what is the difference between a method and a function. We have also dived deep into the relationship between methods, receivers and interfaces. Go methods and interfaces are important features of Go that every Go developer should have at their fingertips.

 

References

Golang Methods
Go methods example

 

Antony Shikubu

Antony Shikubu

He is highly skilled software developer with expertise in Python, Golang, and AWS cloud services. Skilled in building scalable solutions, he specializes in Django, Flask, Pandas, and NumPy for web apps and data processing, ensuring robust and maintainable code for diverse projects. You can reach out to him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment