niksw7
(Niksw7)
June 6, 2024, 11:03am
1
hi Gophers,
I think this could be a valuable feature addition for generics in golang.
type SomeStruct struct {
genericValue interface{}
}
Now lets use generics to extract a specific value type.
This works perfectly
func GetGenericReturnValue[T any](input SomeStruct) (*T, error) {
if val, ok := input.genericValue.(T); ok {
return &val, nil
}
return nil, errors.New("invalid")
}
/* Sample code to demonstrate the above use case
s := SomeStruct{
genericValue: 42,
}
intValue, err := GetGenericReturnValue[int64](s)
if err != nil {
fmt.Println("Returned int value:", *intValue)
}
*/
But now if I want the method to be associated with a struct like below
func (s SomeStruct) GetReturnValue[T any]() (*T,error) {
if val,ok:=s.genericValue.(T) ;ok{
return &val,nil
}
return &val,errors.New("invalid")
}
It gives a syntax error ==> method must have no type parameters
Is there any reason why this above use case should not be supported?
For people wondering what’s difference between 2 and why I am trying to advocate second style—> Encapsulation Principle is what I wanted to respect
lemarkar
(Leo Emar-Kar)
June 6, 2024, 12:10pm
2
Here is the answer why it was not implemented from the start.
https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#No-parameterized-methods
And here is the huge discussion ~3 years, how it could/should be done.
opened 12:40PM - 20 Oct 21 UTC
LanguageChange
v2
Proposal
Proposal-Hold
generics
[According to the Type parameters proposal](https://go.googlesource.com/proposal… /+/refs/heads/master/design/43651-type-parameters.md), it is not allowed to define type parameters in methods.
This limitation prevents to define functional-like stream processing primitives, e.g.:
```go
func (si *stream[IN]) Map[OUT any](f func(IN) OUT) stream[OUT]
```
While I agree that these functional streams might be unefficient and Go is not designed to cover this kind of use cases, I would like to emphasize that Go adoption in stream processing pipelines (e.g. Kafka) is a fact. Allowing type parameters in methods would allow constructing DSLs that would greatly simplify some existing use cases.
Other potential use cases that would benefit from type paremeters in methods:
* DSLs for testing: `Assert(actual).ToBe(expected)`
* DSLs for mocking: `On(obj.Sum).WithArgs(7, 8).ThenReturn(15)`
---
Edited by @ianlancetaylor to add: for a summary of why this has not been approved, please see https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#no-parameterized-methods .
Imho, I see no difference between sugar like struct method and generic func which takes a struct pointer as the first argument. With current generics implementation, the only thing you can do, if you want “generic” method, is to move type to the struct, instead of func itself, something like:
package main
import "fmt"
type Test[T any] struct {
genericValue T
}
func (t *Test[T]) GetValue() T {
return t.genericValue
}
func main() {
t := &Test[int]{42}
fmt.Println(t.GetValue())
t1 := &Test[string]{"Hello"}
fmt.Println(t1.GetValue(), "world!")
}