Cookies management by TermsFeed Cookie Consent

🤏 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!

Buy Me A Coffee

🖖 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