How to convert from `func() *int` to `func() interface{}`?

Issue

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?

Solution

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))
    }

}

https://go.dev/play/p/gDXTPqA1tXL

Answered By – colm.anseo

Answer Checked By – David Marino (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.