Unveiling Generic Iterations over Union Slices (Resolving "T has no core type")
The exploration of Go's generics continues, this time delving into an intriguing challenge: iterating over a union of slices. Our goal is to create a generic function that can handle both slices of integers and slices of floats, then sum their contents.
Our initial attempt encountered an obstacle:
type NumberSlice interface { []int64 | []float64 } func add[N NumberSlice](n N) { for _, v := range n { fmt.Println(v) } }
We received the error "cannot range over n (variable of type N constrained by NumberSlice) (N has no core type)." This error stems from the lack of a core type for the generic interface constraint.
Understanding core types is crucial. A core type exists when the type set of an interface has a single underlying type or consists only of channel types with an identical element type and directional channels with the same direction. Unfortunately, our interface constraint does not satisfy these conditions due to its two underlying types, []int64 and []float64.
To resolve this issue, we can redefine our interface to require the base types and pass a slice of the base type as the function argument:
type Number interface { int64 | float64 } func add[N Number](n []N) { for _, v := range n { fmt.Println(v) } }
Alternatively, we can use a more verbose approach with a specialized NumberSlice type parameter:
type NumberSlice[N int64 | float64] interface { ~[]N } func add[S NumberSlice[N], N int64 | float64](n S) { for _, v := range n { fmt.Println(v) } }
By utilizing these techniques, we can effectively iterate over union slices and perform desired operations in our generic functions.
The above is the detailed content of How to Iterate Over Union Slices in Go Generics and Solve the 'T has no core type' Error?. For more information, please follow other related articles on the PHP Chinese website!