I am testing generics in go 1.18 and looked at this example. I would like to recreate that example but be able to pass in an int slice or a float slice and in the function I would sum everything in the slice.
This is when I ran into some issues while iterating over the slices. Here's what I've tried:
package main import "fmt" // numberslice constraint type numberslice interface { []int64 | []float64 } func add[n numberslice](n n) { // want: to range over n and print value of v for _, v := range n { fmt.println(v) } } func main() { ints := []int64{1, 2} add(ints) }
I get the error:
cannot range over n (variable of type N constrained by NumberSlice) (N has no core type)
How do I achieve this goal?
The core type of the interface (including interface constraints) is defined as follows:
An interface t has a core type if one of the following conditions is met: satisfy:
There is a single typeu
, which is the underlying type of all types in the t type set
Or the type set of t contains only channel types with the same element type e, and all directed channels have the same direction.
Your interface constraint has no core type because it has two underlying types: []int64
and []float64
.
So you can't use it where a core type is required. Especially range
and make
.
You can change the interface to require a basic type and then specify the slice in the function signature:
// still no core type... type number interface { int64 | float64 } // ...but the argument will be instantiated with either int64 or float64 func add[n number](n []n) { for _, v := range n { fmt.println(v) } }
This also works, but is more verbose:
type NumberSlice[N int64 | float64] interface { // one core type []N ~[]N } func add[S NumberSlice[N], N int64 | float64](n S) { for _, v := range n { fmt.Println(v) } }
The above is the detailed content of How to iterate over the union of slices passed in a generic function? (T coreless type). For more information, please follow other related articles on the PHP Chinese website!