I'd like to have something like the following function:
func decorateFn(fn func() interface{}) interface{} {
decorate()
return fn()
}
func decorateFnInt(fn func() *int) *int {
return decorateFn(fn).(*int)
}
Using decorateFn((func() interface{})(fn)).(*int)
doesn't work. Is it possible to convert func() *int
to func() interface{}
? If so, how?
CodePudding user response:
With go 1.18
you can use generics to achieve this - ensuring compile-time type safety and no runtime type assertions:
func decorateFn[T any](fn func() T) T {
decorate()
return fn()
}
func decorateFnInt(fn func() *int) *int {
return decorateFn(fn)
}
The function decorateFn
's type constraint can be inferred at compile-time by inspecting fn
's type.
https://go.dev/play/p/AAByiBFRQch
EDIT: if you are stuck on go 1.17
and cannot use generics, you can use interface{}
for the function parameter, but any type decisions must be performed at runtime. You could try a type switch:
func decorateFn(v interface{}) interface{} {
decorate()
switch t := v.(type) {
case func() *int:
return t()
case func() *string:
return t()
default:
panic(fmt.Sprintf("unsupported type: %T", v))
}
}