Я вызываю функцию из другой библиотеки, сигнатура возврата которой определена следующим образом:
(*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
Может кто-нибудь помочь здесь? Что не так с кодом?
Какую версию го вы используете? Насколько я понимаю, дженерики не были доступны до версии 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
}
Отличная работа, дающая первый ответ! Спасибо. Я бы посоветовал вам изменить это предложение: «Несколько мелких проблем, но ваш ответ студента...», чтобы получилось два предложения без неуклюжего «но». Например: «Несколько небольших вопросов. Ваш ответ студента…»
Спасибо! Даже не думал об этом, но вы правы на 100%. Что-то еще, что, по вашему мнению, я должен изменить? Я все еще новичок в дженериках, поэтому я не уверен, что формулировка, которую я иногда использовал, верна или нет.
Можете ли вы опубликовать пример со ссылкой на игровую площадку, чтобы воспроизвести это? См. Как создать минимальный воспроизводимый пример