'Facing issue with having generic as return type in Golang
I'm invoking a function from another library whose return signature is defined as under:
(*studentlib.Student[StudentResponse], error)
Student
is defined as:
type Student[T any] struct {
st *students.Student
xyz *T
}
StudentResponse
is defined as:
type StudentResponse struct {
}
In my method signature, where I defined the return type as follows:
func abc() (*studentlib.Student[StudentResponse], error) {
// do something here
}
But for the function return parameters, I keep getting errors like the following:
missing ',' in parameter list
Can someone please help here? What's wrong with the code?
Solution 1:[1]
What version of go are you using? From what I understand, generics weren't available until version 1.18. If you are using version 1.18 or above, I would first off try to give different names to your Student structs. It's a little confusing from a readability standpoint to have multiple structs name Student.
Getting into the issue, I think the biggest problem is that your 'abc' function has no way to know what generic type it needs to return since it's not taking an argument. Also, your 'abc' func needs to have the generic type included in the declaration.
A few smaller issues. Your StudentResponse struct should be an interface instead. Separate the specific data types that you want to included by the '|' char.
With that being said, here is how you would get your code to work:
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
}
If you want to use a pointer for xyz in student, you could do it this way:
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
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |