Home  >  Article  >  Backend Development  >  How to iterate over the union of slices passed in a generic function? (T coreless type)

How to iterate over the union of slices passed in a generic function? (T coreless type)

WBOY
WBOYforward
2024-02-06 08:50:08357browse

如何迭代通用函数中传递的切片并集? (T无芯型)

Question content

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?


Correct answer


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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete