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)) }
existmain
In the function, the code initializes two maps, which are used for storage.int64
Types andfloat64
Value of type. Next, the code uses non-genericSumInts
andSumFloats
Functions to calculate the sum of all values in these two maps and print out the result. Then, the code uses genericSumIntsOrFloats
Functions 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 constraintsSumNumbers
To 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!