Столкнувшись с проблемой использования универсального типа возвращаемого значения в Golang

Я вызываю функцию из другой библиотеки, сигнатура возврата которой определена следующим образом:

(*studentlib.Student[StudentResponse], error)

Student определяется как:

type Student[T any] struct {
    st *students.Student
    xyz *T
}

StudentResponse определяется как:

type StudentResponse struct {
    
}

В сигнатуре моего метода я определил тип возвращаемого значения следующим образом:

func abc() (*studentlib.Student[StudentResponse], error) {
   // do something here
}

Но для параметров возврата функции я продолжаю получать ошибки, подобные следующим:

missing ',' in parameter list

Может кто-нибудь помочь здесь? Что не так с кодом?

Можете ли вы опубликовать пример со ссылкой на игровую площадку, чтобы воспроизвести это? См. Как создать минимальный воспроизводимый пример

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

Ответы 1

Ответ принят как подходящий

Какую версию го вы используете? Насколько я понимаю, дженерики не были доступны до версии 1.18. Если вы используете версию 1.18 или выше, я бы сначала попытался дать разные имена вашим структурам Student. С точки зрения удобочитаемости несколько структур с именами Student немного сбивают с толку.

Приступая к проблеме, я думаю, что самая большая проблема заключается в том, что ваша функция «abc» не имеет возможности узнать, какой общий тип ей нужно вернуть, поскольку она не принимает аргумент. Кроме того, ваша функция 'abc' должна иметь общий тип, включенный в объявление.

Несколько мелких проблем. Вместо этого ваша структура StudentResponse должна быть интерфейсом. Разделите конкретные типы данных, которые вы хотите включить, с помощью '|' чар.

С учетом сказанного, вот как вы можете заставить свой код работать:

package main

import (
    "fmt"
)

type Student[T any] struct {
    st string
    xyz T
}

type StudentResponse interface {
    int64 | float64
}

func main() {
    tmp1 := Student[int64]{ // will not throw an error. generic type is defined in StudentResponse
        st: "Testing",
        xyz: 15,
    }
    /*tmp2 := Student[string]{ // will throw an error if used in 'abc' func. generic type not defined in Student Response
        st: "Testing",
        xyz: "15",
    }*/
    
    resp, err := abc(&tmp1)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(resp)
}

func abc[T StudentResponse](s *Student[T]) (*Student[T], error) {
    // do something here
    err := fmt.Errorf("error: %s", "some error") // being used simply to have an error return value
    return s, err
 }

Если вы хотите использовать указатель для xyz в студенте, вы можете сделать это следующим образом:

package main

import (
    "fmt"
)

type Student[T any] struct {
    st string
    xyz *T
}

type StudentInfo struct {
    Age float64
    Weight  int64
}

type StudentGrades struct {
    GPA float64
    CreditHours int64
}

type StudentResponse interface {
    StudentInfo | StudentGrades
}

func main() {
    info := StudentInfo{
        Age: 22.5,
        Weight: 135,
    }
    grades := StudentGrades{
        GPA: 3.6,
        CreditHours: 15,
    }
    tmp1 := Student[StudentInfo]{
        st: "tmp1",
        xyz: &info,
    }
    tmp2 := Student[StudentGrades]{
        st: "tmp2",
        xyz: &grades,
    }
    
    resp1, err1 := abc(&tmp1)
    if err1 != nil {
        fmt.Println(err1)
    }

    resp2, err2 := abc(&tmp2)
    if err2 != nil {
        fmt.Println(err2)
    }
    fmt.Println(resp1)
    fmt.Println(resp1.xyz)

    fmt.Println(resp2)
    fmt.Println(resp2.xyz)
}

func abc[T StudentResponse](s *Student[T]) (*Student[T], error) {
    // do something here
    err := fmt.Errorf("error: %s", "some error") // being used simply to have an error return value
    return s, err
 }

Отличная работа, дающая первый ответ! Спасибо. Я бы посоветовал вам изменить это предложение: «Несколько мелких проблем, но ваш ответ студента...», чтобы получилось два предложения без неуклюжего «но». Например: «Несколько небольших вопросов. Ваш ответ студента…»

Kevin Buchs 06.05.2022 23:39

Спасибо! Даже не думал об этом, но вы правы на 100%. Что-то еще, что, по вашему мнению, я должен изменить? Я все еще новичок в дженериках, поэтому я не уверен, что формулировка, которую я иногда использовал, верна или нет.

Grant 07.05.2022 06:32

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