Golang generics : what we need to know?

Golang generics : what we need to know?

Golang is a strongly typed programming language, meaning that each variable in Golang is associated with a specific data type. This characteristic is not unique to Golang but is shared with several other programming languages like C, C++, Java, and C#. One challenge posed by strongly typed programming languages is the need to handle similar operations that involve different data types. For instance, the addition operation may need to work seamlessly with both integer and floating-point variables. As developers, it's advisable to create code blocks that are not constrained to a particular data type or data structure.

Because of this challenge, Go 1.18 came with a new concept. It introduced the concept of generics. Before the introduction of generics in Go, developers had to write multiple functions to handle different types of data. This approach was often cumbersome and led to code duplication. With generics, developers can write more concise and reusable code that can handle different types of data. Generic types (simply called Generics) are codes that allow us to use them for various functions by just altering the function types. Generics were created to make code independent of types and functions.

In Golang, the standard add function typically accepts arguments, such as integers a and b, but it cannot handle them as floats to produce a result. Here's a visual comparison of this scenario both with and without the incorporation of generics:

Go before generics:

Let's say we have a and b as integers and we've to make an add operation, it's easy to implement the add function that returns a + b. but when a and b are float variables, the add function can't receive them as arguments, so we have to create another add function that receives float variables. Here is the block of code that explains it well:

package main

import "fmt"

func addInt(a int, b int) int {
    return a + b
}
func addFloat(a float64, b float64) float64 {
    return a + b
}
func main() {
fmt.Println(addInt(5,6))
fmt.Println(addFloat(5.1,6.6))
}

Go after generics:

With generics, this can be done with just one function:

package main

import "fmt"

func add[T int | float64](a T, b T) T {
    return a + b
}
func main() {
    fmt.Println(add(1, 5))
    fmt.Println(add(1.2, 1.3))
}

How to create a generic type?

In some cases you want your generics to accept not just integer variables but also integers of base 8, integers of base 16, floats of base 32, floats of base 64 and others. For instance, you can declare an interface called Num:

package main

import "fmt"
type Num interface {
    int8 | int16 | float32 | float64
}
func add[T Num](a T, b T) T {
    return a + b
}
func main() {
    fmt.Println(add(1, 5))
    fmt.Println(add(1.2, 1.3))
}

That's it for today's article.

Did you find this article valuable?

Support mohamed fares ben ayed by becoming a sponsor. Any amount is appreciated!