When To Use Generics in Go

When to Use Generics in Go's picture

Generic was a very big issue throughout the Golang Developer's Community before the release of version 1.18 Go Programming Language. It was an issue in the community because developers were unable to use Generics in Go.

I know, it might sound unusual to you because maybe you don’t know what exactly Generics is. In this blog, I will be delivering the knowledge of Generics, How to Use it, and most importantly when to use it.

So let’s understand Generics first but before that, I have mentioned some prerequisites, so that you can be prepared with it and get a better understanding of the concept through this explanation blog.


Before proceeding, I would like to request you go through the concepts that I will be mentioning below to get proper clarity on the concepts explained in this blog. To understand generic first you need to be prepared with the basic concepts of Golang like Variables, Constants, Datatypes, I/O Format, Slices, Struct, Functions, Maps, Parameters, and Arguments. Then on the other hand you should have Golang installed on your system. Now, let us proceed toward understanding what exactly Generics is.

What is Generics

In simple words, Generic enables the creation of code with types that can be defined later and implemented as required. In other words, Generics in Go relates to the ability to create types or functions that are not type-specific and may be used with a variety of kinds.

As a result, you can create code that is more general and reusable and can be used for many other types. As an illustration, you could create a function that sorts an integer slice in ascending order.

For each type that you wished to sort, you would have to create a separate version of this function without generics (e.g. int, float64, string, etc.). As long as the type has a predetermined ordering, you can use generics to create a single version of the function that can sort slices of any type.

1 2 3 4 5 func Sort(slice interface{}) { n := reflect.ValueOf(slice).Len() s := reflect.ValueOf(slice).Slice(0,n).Interface().(sort.Interface) sort.Sort(s) }

The above is an example of a generic function that sorts a slice of any type that implements the sort.interface interface. Slices of any type that supports the sorting operation can be sorted using this function. Slices of texts or numbers are examples of interfaces.

Although they can be a potent tool for creating reusable, adaptable code in Go, generics can also be tricky to work with. Start with some simpler examples if you're unfamiliar with Go and generics, then progress to more sophisticated usage of generics. Let me provide a basic example to make it easier to grab the concept.

1 2 3 4 5 func Swap(a, b *int) { temp := *a *a = *b *b = temp }

This function swaps the values of two pointers to integers that it is given as an argument by utilizing a temporary variable. You would call this function as follows to swap the values of the two variables x and y:

1 2 3 4 5 x := 1 y := 2 Swap(&x, &y) fmt.Println(x, y) // Output: 2 1

Because it may be used to swap the values of any two int variables, regardless of their names or values, therefore you can refer to this function as generic.

Limitations of Generics

In this section, I will be explaining the limitations of Generics in Go. There are a few limitations that in my perspective should not be avoided when you are preparing yourself for Golang Programming. I have mentioned them below,

  • You cannot specify a type parameter when defining a function or type in Go. This means that, unlike in some other languages, you cannot create a generic function or type that works with any type. Instead, to develop generic functions and types that can interact with many types, you must utilize the interface's type and type assertions.
  • Reflection on types or values that have a type of interface is not supported by Go. This implies that you are unable to invoke methods on such a variable or use reflection to investigate the type or value of a variable with an interface type.
  • Go does not provide type-based overloading of functions or methods. As a result, you are unable to declare many iterations of a function or method with the same name that merely differ in the nature of their parameters or return values.

When to use it?

When writing code in Go that may be used with numerous kinds rather than just one type, generics can be a helpful tool. This can make it simpler for you to create more flexible, broad, and reusable code.

Here are a few scenarios in Go where you might think about using generics:

  1. When you need to create a function that can work with different kinds of data. As an illustration, you could create a generic sorting function that can organize slices of any kind.
  2. When you wish to create a type that can store many data types. You may create a generic stack type, for instance, that can store values of any type.
  3. When you need to create a type or function that can consistently perform operations on a variety of kinds. For instance, you could create a generic function that accepts two arguments and always returns the greater of the two.

Generics may not always be the best option, of course. For instance, you might not need to utilize generics if you are working with a limited, fixed collection of types and you do not need to build general, reusable code. In general, before utilizing generics in your codebase, it's a good idea to think about if they will help you produce cleaner, more manageable code. Start with some simpler examples if you're unfamiliar with Go and generics, then progress to more sophisticated usage of generics. I hope this blog was helpful for your learning. I tried to cover most of the things related to generics in this blog, but keep in mind to be prepared with the essentials before beginning with this explanation blog on Golang. This blog will also contribute to the extension of your knowledge that you can optimize Go Programing for both Golang Web Development and Application Development. Happy Coding!

Build Your Golang Team