🤏 Calculate arithmetic mean in Go using Generics

Last updated:
numbers math generics generics-intro

To calculate the arithmetic mean (average value) in Go, you should write your own function that takes a slice of numbers as an input, sum all values in the slice, and divides the sum by the number of elements.

``````package main

import "fmt"

func mean(data []float64) float64 {
if len(data) == 0 {
return 0
}
var sum float64
for _, d := range data {
sum += d
}
return sum / float64(len(data))
}

func main() {
fmt.Println(mean([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))
}
``````

This function requires that the input slice to be of a certain type, such as `float64`. In case you want to calculate the mean for a slice of, for example, `int` values, until recently you had to write a separate function that differed only in that it accepted an `int` slice as an argument. Another solution was to convert the slice to `float64` before the calculation. However, the new version of Go 1.18, which introduced Generics, allows you to simplify this problem. All you need to do is write a generic `mean()` function that takes a slice of any numeric type.

``````package main

import (
"fmt"

"golang.org/x/exp/constraints"
)

type Number interface {
constraints.Float | constraints.Integer
}

func mean[T Number](data []T) float64 {
if len(data) == 0 {
return 0
}
var sum float64
for _, d := range data {
sum += float64(d)
}
return sum / float64(len(data))
}

func main() {
fmt.Println(mean([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))
fmt.Println(mean([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))
}
``````

If you are not already familiar with the basics of Generics in Go, check out our series of articles: Introduction to Go Generics by example.

Check also our example on how to calculate median in Go.

In the example above, we start with the custom constraint declaration. The `Number` interface is a type set being union of `constraints.Float` and `constraints.Integer`.

This is a new feature released along with Generics in Go 1.18 - now interfaces can have not only a set of methods but also a set of types. Just use the `|` operator to declare the set of types that our generic function should accept. In our case, we accept `constraints.Float` and `constraints.Integer` types, which are themselves type sets containing all floating and integer point types.

The rest of the new `mean()` function is the same as in the non-generic version. The only difference is that we use type `T` instead of `float64` for the input data. The function result is still `float64`, because no matter if the input is a slice of integers or floating-point numbers, we can get a floating-point number as the result of the mean.

Thank you for being on our site 😊. If you like our tutorials and examples, please consider supporting us with a cup of coffee and we'll turn it into more great Go examples.

Have a great day!

🖖 Calculate Median in Go using Generics

Learn how to find “the middle value” of a slice
numbers math generics generics-intro

🫘 Count the occurrences of an element in a slice in Go

Learn how to count elements in a slice that meet certain conditions
introduction generics generics-intro

🧊 Cube root in Go

shorts numbers math