How To Write Generic Helper Functions With Go 1.18 — Part 2
Let’s create a map function that invokes a callback on each element in an array/slice

Today, we’re going to create a function that calls a callback for each element of our array/slice to adjust the respective value and return it. Now, you may be asking yourself, “What the heck! Why would I want to do that?”. Well, imagine if you had to capitalize every word in an array, invert Boolean values, or multiply every number by another.
There are many situations like this where such a function could be useful. Unfortunately, in Go, you have to develop such a map function yourself. But don’t worry. Today we’re going to look at how to implement this kind of function yourself. So buckle up, and let’s get started.
This is the third article of my new series. In the first part, I already talked a little about generics. This is not a requirement, but it might be helpful.
Intro
One thing before we begin. For our solution, we need generics. This means we have to use Golang version 1.18 again.
Approach
What we want is pretty simple and can be broken down into three steps:
- We want to call a callback with each element in an array/slice.
- The adjusted values should be stored in a new slice.
- In the end, the function should return the adjusted values.
Solution
To do this, our function needs to take two arguments. The first is our array, and the second is the callback. Below, you can see our main Map
function. We loop through our array, call our callback with each item, and append the adjusted values to our new slice. In the end, all we have to do is return our new slice.
If we only have to adjust the values of an array/slice from one type, this solution is completely enough. But if there are arrays with different types, we need to implement the same function for each type. This leads to a totally unwieldy and duplicate codebase. To avoid this, we can use generics as in the first article. But this time, we use a different generic type.
Improvements
Last time, we used the “comparable” generic type. This time, we need the generic type “any.” As you can see below, we need to write our generic name T
in brackets right after the function name and give it the type “any.” We also give the two parameters the type T
as well as the temporary result slice. This allows us to specify what kind of array our function expects and what type the resulting slice should be.
To use it, we have to make the following function call:Map[int]([1, 2], func(num int){return num + 1})
.
The word “int” inside the brackets specifies our generic type.
Benchmark
In the end, we run table benchmark tests for each solution to prove that we don’t have any critical performance issues when using the generic version. Below you can see the test command as well as the test result.
go test -bench="BenchmarkMap" -run=^# -benchtime=10000x

As last time, the number of nanoseconds per operation is almost the same for the static version compared to the generic version. In fact, if you look at the fourth sample, the opposite is true. The fourth example for the MapInt
function stands out a bit, but that only happens on this run. I ran a few more tests, and overall, both tests took the same amount of time per operation.
Conclusion
I hope the approach of invoking a callback on each element in an array was interesting and helpful. If you have another solution, something to mention, or questions, it would be great if you leave them in the comments. See you soon.
P.S. This is the third article of a new series I have planned. Over the next few weeks, I’ll look at various generic helper functions, interesting benchmarks, and useful features.
If you’re as excited as I am, stay tuned!