GOOGLE ADS

суббота, 7 мая 2022 г.

Столкнувшись с проблемой использования универсального типа возвращаемого значения в 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

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


Решение проблемы

Какую версию го вы используете? Насколько я понимаю, дженерики не были доступны до версии 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
}

Комментариев нет:

Отправить комментарий

Laravel Datatable addColumn returns ID of one record only

Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...