Think about the next snippet (playground)
bundle foremost
import "fmt"
kind Foo struct{}
func foo() (Foo, error) {
return Foo{}, nil
}
kind Bar struct{}
func bar() (Bar, error) {
return Bar{}, nil
}
func Wrap(fn func() (any, error)) func() string {
return func() string {
d, err := fn()
if err != nil {
return err.Error()
} else {
return fmt.Dash(d)
}
}
}
func foremost() {
_ = Wrap(foo)
_ = Wrap(bar)
}
Making an attempt to compile this yields the next error:
./prog.go:29:11: can't use foo (worth of kind func() (Foo, error)) as func() (any, error) worth in argument to Wrap
./prog.go:30:11: can't use bar (worth of kind func() (Bar, error)) as func() (any, error) worth in argument to Wrap
Any option to change the signature of Wrap
to permit for this? A workaround at present is to do
func foremost() {
_ = Wrap(func() (any, error) { return foo() })
}
however that’s fairly cumbersome.
You would use generics.
Substitute
func Wrap(fn func() (any, error)) func() string {
with
func Wrap[T any](fn func() (T, error)) func() string {
1 Like
When you’re utilizing generics you can create a generic kind extra restrictive than any
. For instance,
func Wrap[T Foo | Bar](fn func() (T, error)) func() string {
...
}
Thanks for the suggestion, however there are literally fairly a number of sorts that might make this cumbersome once more. Because the implementation of Wrap
really does work with any
object, there is no such thing as a want to limit it artificially.