Я тестирую дженерики в версии 1.18 и взглянул на этот пример. Я хотел бы воссоздать этот пример, но вместо этого иметь возможность передать фрагмент int или фрагмент float, а в функции я просто суммирую все в фрагменте.
Это когда я столкнулся с некоторыми проблемами, просто повторяя срез. Вот что я пробовал:
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)
}
Как мне это сделать?
Может ли что-то подобное работать для вас?
package main
import "fmt"
type NumberOrFloat interface {
int64 | float64
}
func add[N NumberOrFloat](n []N) {
for _, v := range n {
fmt.Println(v)
}
}
func main() {
ints := []int64{1, 2}
add(ints)
}
Разница здесь в том, что вы определяете ограничения типов для элементов массива (а не для типов массивов): []N
основной тип для интерфейса (включая ограничение интерфейса) определяется следующим образом:
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.
У вашего ограничения интерфейса нет основного типа, потому что оно имеет базовые типы два: []int64
и []float64
.
Поэтому вы не можете использовать его там, где требуется основной тип. Особенно range
и make
.
Вы можете изменить интерфейс, чтобы он требовал базовых типов, а затем указать срез в сигнатуре функции:
// 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)
}
}
Это тоже работает, но более подробно:
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)
}
}
Вау, спасибо, что это! ^_^ (и такой быстрый ответ!)
Как сейчас написано, ваш ответ неясен. Пожалуйста, редактировать, чтобы добавить дополнительную информацию, которая поможет другим понять, как это относится к заданному вопросу. Дополнительную информацию о том, как писать хорошие ответы, можно найти в справочном центре.