Generic function for types with common method name but different return type

477 views
Skip to first unread message

Oleh Lomaka

unread,
Sep 9, 2023, 8:17:55 PM9/9/23
to golang-nuts
Hello everybody,

Gophers' superpower is required and highly appreciated.

I have two types, A and B, each of which has a method named "M". This method accepts a string and returns an instance of the type it is declared on.

```go
type A struct {}
func (a A) M (string) A {
    return a
}
type B struct {}
func (b B) M (string) B {
   return b
}
```

What's the best way to declare a generic function that receives an instance of one of these types along with a string? Depending on the string, this function should either return the instance it received or call method M on it and return the instance produced by this method.

Currently, I've come up with two solutions, but I'm not entirely satisfied with either:

https://go.dev/play/p/h5jzISRyTkF In this approach, I'm not fond of how I must call the f function on line 30. Without specifying a type parameter, the call fails to compile. Additionally, I'm concerned about potential panics on line 23. If I expand the code with new types in the future, there's a risk of type assertion failures.

https://go.dev/play/p/rHHjV_A-hvK While this solution appears cleaner, it's prone to panicking if I introduce another type with an incompatible M signature (or without M method completely)

Maybe someone has better ideas.

Thank you.
All the best,

Brian Candler

unread,
Sep 10, 2023, 4:00:42 AM9/10/23
to golang-nuts
https://go.dev/play/p/h5jzISRyTkF In this approach, I'm not fond of how I must call the f function on line 30. Without specifying a type parameter, the call fails to compile.

If I replace f[A](a, "") with f(a, "") it still works for me, in the playground.

What go version are you using? There were several improvements to type inference for generics in 1.21.

Oleh Lomaka

unread,
Sep 10, 2023, 6:48:17 AM9/10/23
to golang-nuts


Hey, turns out you're right! I can call it like `f(a, "")`. I was naive to believe Goland when it indicated an error. I need to submit a bug report to JetBrains. That's good, because I feel this method is more reliable than the second one. However, I'm still not a fan of the type assertion in `i.(T)` that could cause a panic.

But I think I still need to annotate the call with the type parameter, as most of the team uses Goland and they'll see it as an error if I omit it :(

Thanks. 
Reply all
Reply to author
Forward
0 new messages