Как перебрать объединение фрагментов, переданных в общей функции? (T не имеет основного типа)

Я тестирую дженерики в версии 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)
}

Как мне это сделать?

Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
2
0
133
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Может ли что-то подобное работать для вас?

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

Как сейчас написано, ваш ответ неясен. Пожалуйста, редактировать, чтобы добавить дополнительную информацию, которая поможет другим понять, как это относится к заданному вопросу. Дополнительную информацию о том, как писать хорошие ответы, можно найти в справочном центре.

Community 18.03.2022 03:09
Ответ принят как подходящий

основной тип для интерфейса (включая ограничение интерфейса) определяется следующим образом:

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 T

  • or 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)
    }
}

Вау, спасибо, что это! ^_^ (и такой быстрый ответ!)

Avery Carty 17.03.2022 20:03

Другие вопросы по теме