SoFunction
Updated on 2025-03-03

A detailed exploration of Go generic design

Go generics

The design incorporates modern language styles, such as type constraints, which we can also see in TypeScript and Python.

Today I will taste this generic design, compare it with the old version of Go, and add type restrictions examples.

demo

Go straight to the topic:

package main
import "fmt"
// The code first defines an interface type `Number`,// It contains two types: `int64` and `float64`.// This interface type can be used to limit the type parameter range of generic functions.type Number interface {
    int64 | float64
}
// Two non-generic functions `SumInts` and `SumFloats` are defined,// They are used to calculate the sum of all values ​​in the map of type `int64` and type `float64` respectively.// SumInts adds together the values of m.
func SumInts(m map[string]int64) int64 {
    var s int64
    for _, v := range m {
        s += v
    }
    return s
}
// SumFloats adds together the values of m.
func SumFloats(m map[string]float64) float64 {
    var s float64
    for _, v := range m {
        s += v
    }
    return s
}
// Defines a generic function `SumIntsOrFloats`, which accepts a map of type `map[K]V` and returns the sum of all values ​​in this map.// This function uses two type parameters `K` and `V`, where the type of `V` can be one of `int64` or `float64`.// The `for range` statement is used in the function to iterate over the values ​​in the map and calculate their sum, and finally return this sum.// SumIntsOrFloats sums the values of map m. It supports both floats and integers
// as map values.
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
    var s V
    for _, v := range m {
        s += v
    }
    return s
}
// `SumNumbers`, its type parameter `V` must implement the `Number` interface type.// This function is similar to the `SumIntsOrFloats` function, the difference is that it uses the `Number` interface type to limit the value range of `V`// Only types that implement the `Number` interface type can be used as the value type of `V`.// SumNumbers sums the values of map m. Its supports both integers
// and floats as map values.
func SumNumbers[K comparable, V Number](m map[K]V) V {
    var s V
    for _, v := range m {
        s += v
    }
    return s
}
func main() {
    // Initialize a map for the integer values
    ints := map[string]int64{
        "first": 34,
        "second": 12,
    }
    // Initialize a map for the float values
    floats := map[string]float64{
        "first": 35.98,
        "second": 26.99,
    }
    ("Non-Generic Sums: %v and %v\n",
        SumInts(ints),
        SumFloats(floats))
    ("Generic Sums: %v and %v\n",
        SumIntsOrFloats[string, int64](ints),
        SumIntsOrFloats[string, float64](floats))
    ("Generic Sums, type parameters inferred: %v and %v\n",
        SumIntsOrFloats(ints),
        SumIntsOrFloats(floats))
    ("Generic Sums with Constraint: %v and %v\n",
        SumNumbers(ints),
        SumNumbers(floats))
}

existmainIn the function, the code initializes two maps, which are used for storage.int64Types andfloat64Value of type. Next, the code uses non-genericSumIntsandSumFloatsFunctions to calculate the sum of all values ​​in these two maps and print out the result. Then, the code uses genericSumIntsOrFloatsFunctions to calculate the sum of all values ​​in these two maps and print out the result. Finally, the code uses a generic function with type constraintsSumNumbersTo calculate the sum of all values ​​in these two maps and print out the result.

This code demonstrates the application of generics in Go. Through this example, we can better understand the generic functions in Go.

If we do not use generics, we may have to copy and paste multiple times, and the code is not easy to maintain.

If type restrictions are not used, once a type is added, the original module will not be easy to maintain.

We use type limitation, which is the so-called type contract, to reach a consensus. You can tell at a glance that this is the same as the interface characteristics represented by interface.

The above is a detailed exploration of the detailed content of Go generic generic design. For more information about Go generic generic design, please pay attention to my other related articles!