Interface in Golang

Learn via video courses
Topics Covered

Overview

The interface is a special type in Golang. All types are used to define the state while an interface is used to define the behaviour. For example, if it barks, waves its tale, and bites then it is a dog. Any struct which satisfies this behaviour then struct is a type of that interface.

For creating scalable applications, it is essential to write modular, reusable code. By reducing the need to make the same change numerous times, working in this way makes code easier to maintain and that's why the interface in golang was introduced. The method for doing this differs depending on the language. In this article, we will learn about the interface in golang and how we can declare or achieve it.

Introduction to Interface in Golang

An interface in golang is a collection of methods that represent standard behaviour for different data types. Interfaces define (not declare) the behaviour. An interface does not include the implementation of the functions; only their signatures are present. However, In Go, there is no keyword to explicitly state that type of this interface. If a type is satisfying all the methods of an interface then it is of interface type.

An interface's main responsibility is to offer method signatures, which consist of the method name, input arguments, and return types. A Type (such as a struct type) is responsible for declaring and implementing methods. Any struct which satisfies this behaviour then struct is a type of that interface.

Syntax

How to Create an Interface?

Interface in golang can be created by using the following syntax:

Declaring and Implementing an Interface

In Golang, we must implement all the methods which are declared in the interface. Generally, the methods consist of names and parameters.

Output:

try to run by yourself!

Explanation:

  • We've created the Shape interface and the struct type Rect in the above programme. Then we defined methods for the Rect type, such as Area and Perimeter, so Rect implemented those methods.
  • The Rect struct type implements the Shape interface because the Shape interface defines these methods. The Shape interface is being implemented by Rect automatically because we haven't forced it to. As a result, interfaces in Go are said to be implicitly implemented.
  • A variable of a type that implements an interface can also be referred to as the type of an interface. By defining a Shape-type nil interface and assigning a Rect-type struct, we can confirm that.

We have just achieved polymorphism.

Rect implements the Shape interface, hence this is true. As can be seen from the results above, the dynamic type of s is now Rect, and the dynamic value of s is the value of the struct Rect, which is 5 4.

  • Because it returns the type of its underlying dynamic value when we access an interface type and hides its static type, the dynamic type of an interface is occasionally referred to as a concrete type.
  • Since the interface Shape defines the Area method and the concrete type of s is Rect, which implements the Area method, we can call the Area method on s. When interfaces carry a dynamic value, this method will be called.

Furthermore, s and r have the same dynamic type (struct of type Rect) and dynamic value (5 4), allowing for comparison.

Multiple Interfaces in Go Implementation

It is possible to use several interfaces concurrently. If every function is implemented, then every interface is also implemented by the type. 

For Example:

Output:

Explanation

  • We generated Shape and Object interfaces using the Area and Volume methods, respectively, in the programme shown above.
  • Struct type Cube implements both of these interfaces since it implements both of these functions. Therefore, we can give a variable of type Shape or Object a value of struct type Cube.
  • We anticipate that s will have a dynamic value of c and that o will do the same. Because it defines the Area method, we utilised the Area method on s of type Shape interface and Volume method on o of type Object interface.

try to run by yourself!

What would happen, though, if we applied the Volume method to S and the Area method to O? Let's apply these changes to the above code and observe the outcomes.

This outcome is produced by the above changes.

Multiple interfaces in Go implementation

Reason for failing:

  • Because the static type of s is Shape and the static type of o is Object, this programme won't compile. We received the aforementioned issue because Shape does not specify the Volume method and Object does not define the Area method.
  • The dynamic value of these interfaces, which is a struct of type Cube that implements these methods, must be somehow extracted for it to function. Type assertion can be used to do this.

Important Points

  • Interface Helps to build more modular and decoupled code between different sections of the codebase - It can assist in reducing dependencies between different parts of the codebase.
  • Interfaces enable us to avoid code repetition. We can provide different structs into the same method where we want the same behaviour by using interfaces. 
  • The interface's zero value is nil.
  • A type of interface is referred to be an empty interface if it has no methods. Therefore, every type implements the empty interface.
  • Interface Types: There are two different types of interfaces: static and dynamic. The interface itself is the static type. The interface, however, never refers to static values; instead, it always refers to dynamic values.
  • An interface type variable that holds the value of the Type that implements the interface is known as a dynamic value, and the Type itself is referred to as a dynamic type. It is also referred to as concrete type and concrete value.

Type Assertions

The underlying value that an interface holds can be obtained by type assertion. This means that if an interface variable is assigned a string, the underlying value it holds is the string.

The following is the syntax for a type assertion expression:

where T is either an abstract type or a concrete type, and v is a variable whose type must be an interface type,

Output:

try to run by yourself!

In the above code, we are trying to implement the type along with its value in golang. It contains 3 elements

  • temp, a variable whose type we are asserting is defined as an interface.
  • type, tells which type we are assigning to the variable in our case it's a string.
  • t, used to store the value of our variable 'temp'.

Another Example:

Output:

try to run by yourself!

If type assertion is somehow unsuccessful then it will throw an error referred to as a “panic” in Go.

For Example, if we refer to the above program only and just change our integer value to a string it will panic,

Output:

try to run by yourself!

It will now gives us an error as the value of the interface is string and a.(int) is false, it will panic here and terminates.

Type Switch

  • In Go, a type-switch is similar to a switch statement, but with types instead.
  • Type switches are switch blocks where a type is provided as an interface value rather than a standard value. The operations are then carried out when the type has been matched and checked. The code below shows how to do this:

Output:

try to run by yourself!

In the above code, we implemented a switch with multiple cases for different types.

Note: The 'break' keyword at the end of each case in the switch is not required in Golang.

Why It is important?

  • Type switches enable us to run specified programmes for specific types.

Switch Case vs Type Switches

Switch casings and type-switches are very similar. The only difference between them is that type-switch can be utilised to check types and execute type-specific code. This is why type switches are so helpful, but a standard switch accomplishes the same task without the use of types. Use values in the switch statement.

Practical Use of an Interface

Interfaces are extremely helpful for methods and functions that require arguments of dynamic types, like the Println function, which takes any kind of value.

It is simple to work with several types when they all implement the same interface. So, whenever possible, we should go with interfaces.

Let's take an example to look at the practical use of interface,

Output:

try to run by yourself!

  • In the above code, we have created two types of employees i.e Contract and Permanent basis that is defined by using struct. The salary of a contract employee is basic pay and the permanent employee is basic pay + pf.Both employeesstructs now implement the SalaryCalculator interface.
  • The totalExpense is using slices []SalaryCalculator as a parameter and passes it which contains both Permanent and Contract types to the totalExpense function which will be used to calculate the expenses by calling the CalculateSalary.

Interface Internal Representation

An interface is internally represented as a tuple (type, value). Value contains the value of the concrete type, and type is the interface's underlying concrete type. Let's see an example to better understand the concept:

Output:

try to run by yourself!

In the above code, the Studying interface contains a method study() and a Student struct type implements that interface. We are assigning variable s to the student and w to the Studying and now the concrete type of s is Studying.

Empty Interface

An interface is referred to as empty if it has no methods or no functions. It is shown as an interface. Every type implements the empty interface since it has no methods.

Here, we have created an empty interface without any methods. For example, fmt.Print accepts any amount of interface argument.

Output:

try to run by yourself!

We have created an empty interface type variable in this area. We receive nil as an output when we print the variable which stands for zero value.

Another Example with Functions:

Output:

try to run by yourself!

The data type of parameters must often be specified in a function declaration when passing values to the function parameters.

However, we can provide parameters of any data type over an empty interface. This example illustrates that we can use an empty interface as a parameter to a particular function also in our case show() function, can be used for any datatype(boolean, string, etc).

Conclusion

  • As we've seen, combining smaller interfaces into larger ones enables us to exchange only the information we need with a function or method.
  • The interface is a custom type used to express a set of one or more method signatures.
  • In Golang, A type assertion retrieves a value of the provided explicit type from an interface value whereas Type switches are switch blocks where a type is provided as an interface value rather than a standard value.