I am testing out generics in go 1.18 and took a look at this example. I would like to recreate that example but instead be able to pass in a slice of int or slice of float instead, and in the function I'll just sum up everything in the slice.
This is when I ran into some issues just iterating the slice. This is what I tried:
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
// got: cannot range over n (variable of type N constrained by NumberSlice)
// (N has no core type)
for _, v := range n {
fmt.Println(v)
}
}
func main() {
ints := []int64{1, 2}
add(ints)
}
How do I accomplish this?
CodePudding user response:
A core type, for an interface (including an interface constraint) is defined as follows:
An interface T has a core type if one of the following conditions is satisfied:
There is a single type
U
which is the underlying type of all types in the type set of Tor the type set of T contains only channel types with identical element type E, and all directional channels have the same direction.
Your interface constraint has no core type, because it has two underlying types: []int64
and []float64
.
Therefore you can't use it where a core type is required. Notably range
and make
.
You can change the interface to require the base types, 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 it's way 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)
}
}
CodePudding user response:
Could something like this work for you?
package main
import "fmt"
type NumberSlice interface {
int64 | float64
}
func add[N NumberSlice](n []N) {
for _, v := range n {
fmt.Println(v)
}
}
func main() {
ints := []int64{1, 2}
add(ints)
}