Anand Prabhala
6-Jan-2023 | 5 min read
Golang or Go programming language has many similarities with that of C but is an improved version. From memory management to garbage collection, it allows developers to write codes for microservices and modular functions of any software. On top of everything, it is also one of the fastest languages in terms of the compilation and execution times of the codes.
To start programming with Golang, there are two major aspects coders need to learn. These are the utility of specific and generic types since Go codes can be reused. Having said that, the following discussion will further illustrate what these types are, their implementation, and how the code snippets behave for each category.
Like every other programming language, Go has several data types like integer, character, string, and many more. When a certain data type is incorporated in the code, the Type interface needs to be called as it encapsulates all the allowable data types mentioned in the program library. Also, any user-defined data type comes under the Type interface as they need to be referenced to a pre-defined datatype.
The Type interface can be further subdivided into generic and specific types.
Generics is available from the Go 1.18 version. It allows developers to define a particular method or function in a general way that will be completely independent of any specific data type. It is like a mold that can be further called in the entire program using different data types.
No particular data type will be defined in the function parameter. Furthermore, Generics allows coders to implement a Type interface, which will further help make the code reusable in various ways according to the programming requirement.
Specific is a particular data type that is passed as the parameter through the function definition. For instance, if you pass integer parameters through a concerned method, the data type to be used will be Int. Similarly, if a method needs to handle characters and strings, the function should define the datatype as char or String, respectively.
Such a function cannot be defined with any other Type format. Therefore, any Go programming module having a specific data type cannot be further reused somewhere else in the entire program.
To understand Generics and Specific Types in Golang, it’s important to check how they can be implemented in the codes. Furthermore, the codes’ working will also give you an exact idea about these types.
So, let’s take an example of a function defined with a specific type.
func main(){
var x int = 20
var y int = 10
var m float32 = 20
var n float32 = 10.5
result := Add(x, y)
// We need to cast data type into int here
resultfloat := Add(int(m), int(n))
// Will return 30
fmt.Println("Result:", result)
// Will return 30 -- Which is wrong, we should get 30.5 but we need a extra function for that to work
fmt.Println("Resultfloat:", resultfloat)
}
// Add will sum the second value with the first
func Add(x, y int) int {
return x + y
}
Here, you are defining the parameter sum of a specific data type, i.e., integer. Therefore, the value it will return will be of integer type, regardless of the values passed through the parameters x and y. Whenever the function Sum is called in the program, it will only return the addition of two integer variables in an integer form. Therefore, the result will be 30 and 30.5 because 0.5 from 10 is removed when float32 datatype is converted into integer.
This can resolved if we have two similar functions Add but involving integer and float datatypes. It not only increases the code length but also introduces lots of complexity.
Now, the function mentioned above can be made independent of the data type and complexity using the concept of Generics and interface. When we use Generics, no particular data type is passed along with the parameters in the function definition.
While declaring the function in Golang using Generic method, there are two parameters passed. These are:
Usually, based on these two parameters, a method can be written as:
func Add [S int] (x, y int) int {
return x+y
}
Here, S is the type parameter and it is capitalized for better understanding. Since we have defined the type as int, the return value will be of the same datatype. On the other hand, x and y are function parameters and their scope is for local variables.
Now, we can use S as the interface to implement Generics. To do so, we will add another possible data type and introduce type constraint. The above code can be written as:
func Add [S int | int32 | float32] (x,y,V) S {
return x+y
}
S is now an interface with Generic property that can implement either r integer or float32 datatype.
You can define an interface with all the possible datatypes you would like to use in the code. This is one of the best ways of implementing Generics.
type Summable interface {
int | int32 | int64 | float312 | float64 | uint | uint32 | uint64
}
Here, Summable is a type constraint which when included in the generic function will make it an interface having provisions for the datatypes being defined in the same.
There are several benefits coders can enjoy with the implementation of Generics in the entire codebase. Some of them are:
In this article, we have walked you through the usage of Generics and Specific Types in Golang. With the introduction of Generics, developers can now use Golang to code complex logic only once and reuse the same by simply passing the Specific Type through the function parameters.